Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

814 lines
29 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation
  3. Module Name:
  4. pedid.h
  5. Abstract:
  6. This is the NT Video port EDID header. It contains the definitions for
  7. the EDID industry standard Extended Display Identification Data structure
  8. as well as macros for accessing the fields of that data structure.
  9. Author:
  10. Bruce McQuistan (brucemc) 20-Sept-1996
  11. Environment:
  12. kernel mode only
  13. Notes:
  14. Based on VESA EDID Specification Version 2, April 9th, 1996
  15. Revision History:
  16. --*/
  17. //
  18. // Form of type stored in display ROM.
  19. //
  20. #pragma pack(1)
  21. typedef struct __EDID_V1 {
  22. UCHAR UC_Header[8];
  23. UCHAR UC_OemIdentification[10];
  24. UCHAR UC_Version[2];
  25. UCHAR UC_BasicDisplayParameters[5];
  26. UCHAR UC_ColorCharacteristics[10];
  27. UCHAR UC_EstablishedTimings[3];
  28. USHORT US_StandardTimingIdentifications[8];
  29. UCHAR UC_Detail1[18];
  30. UCHAR UC_Detail2[18];
  31. UCHAR UC_Detail3[18];
  32. UCHAR UC_Detail4[18];
  33. UCHAR UC_ExtensionFlag;
  34. UCHAR UC_CheckSum;
  35. } EDID_V1, *PEDID_V1;
  36. #pragma pack()
  37. #pragma pack(1)
  38. typedef struct __EDID_V2 {
  39. UCHAR UC_Header[8];
  40. UCHAR UC_OemIdentification[32];
  41. UCHAR UC_SerialNumber[16];
  42. UCHAR UC_Reserved1[8];
  43. UCHAR UC_DisplayInterfaceParameters[15];
  44. UCHAR UC_DisplayDeviceDescription[5];
  45. UCHAR UC_DisplayResponseTime[2];
  46. UCHAR UC_ColorLuminanceDescription[28];
  47. UCHAR UC_DisplaySpatialDescription[10];
  48. UCHAR UC_Reserved2[1];
  49. UCHAR UC_GTFSupportInformation[1];
  50. UCHAR UC_MapOfTimingInformation[2];
  51. UCHAR UC_LuminanceTable[127];
  52. UCHAR UC_CheckSum;
  53. } EDID_V2, *PEDID_V2;
  54. #pragma pack()
  55. //
  56. // EDID decoding routines
  57. //
  58. //
  59. // Useful Bit manifest constants
  60. //
  61. #define EDIDBITNONE 0x00
  62. #define EDIDBIT0 0x01
  63. #define EDIDBIT1 0x02
  64. #define EDIDBIT2 0x04
  65. #define EDIDBIT3 0x08
  66. #define EDIDBIT4 0x10
  67. #define EDIDBIT5 0x20
  68. #define EDIDBIT6 0x40
  69. #define EDIDBIT7 0x80
  70. #define EDIDBIT8 0x100
  71. #define EDIDBIT9 0x200
  72. //
  73. // 3.4) XFER_CHARACTERISTIC is gamma*100 - 100, so invert in USER.
  74. // NOTE: This must be called from USER.
  75. //
  76. #define USER_CONVERT_TO_GAMMA(achar) \
  77. (achar + 100)/100
  78. //
  79. // 4.1) Chromaticity Coordinates Format macro. Use these to convert
  80. // from the binary format to the actual decimal representation.
  81. // NOTE: can only be called from USER.
  82. //
  83. #define USER_CONVERT_CHROMATICITY_FROM_BINARY_TO_DECIMAL(ashort) \
  84. (ashort & EDIDBIT9)*(1/2) + (ashort & EDIDBIT8)*(1/4) + \
  85. (ashort & EDIDBIT7)*(1/8) + (ashort & EDIDBIT6)*(1/16) + \
  86. (ashort & EDIDBIT5)*(1/32) + (ashort & EDIDBIT4)*(1/64) + \
  87. (ashort & EDIDBIT3)*(1/128) + (ashort & EDIDBIT2)*(1/256) + \
  88. (ashort & EDIDBIT1)*(1/512) + (ashort & EDIDBIT0)*(1/1024)
  89. //
  90. // 5.1) Macros for USER to decode the bitfields
  91. //
  92. //
  93. // TIMING_I
  94. #define USER_TIMING_I_IS_720x400x70HZ(timing1) timing1 & EDIDBIT7
  95. #define USER_TIMING_I_IS_720x400x88HZ(timing1) timing1 & EDIDBIT6
  96. #define USER_TIMING_I_IS_640x480x60HZ(timing1) timing1 & EDIDBIT5
  97. #define USER_TIMING_I_IS_640x480x67HZ(timing1) timing1 & EDIDBIT4
  98. #define USER_TIMING_I_IS_640x480x72HZ(timing1) timing1 & EDIDBIT3
  99. #define USER_TIMING_I_IS_640x480x75HZ(timing1) timing1 & EDIDBIT2
  100. #define USER_TIMING_I_IS_800x600x56HZ(timing1) timing1 & EDIDBIT1
  101. #define USER_TIMING_I_IS_800x600x60HZ(timing1) timing1 & EDIDBIT0
  102. // TIMING_II
  103. #define USER_TIMING_II_IS_800x600x72HZ(timing2) timing2 & EDIDBIT7
  104. #define USER_TIMING_II_IS_800x600x75HZ(timing2) timing2 & EDIDBIT6
  105. #define USER_TIMING_II_IS_720x624x75HZ(timing2) timing2 & EDIDBIT5
  106. #define USER_TIMING_II_IS_1024x768x87HZ(timing2) timing2 & EDIDBIT4
  107. #define USER_TIMING_II_IS_1024x768x60HZ(timing2) timing2 & EDIDBIT3
  108. #define USER_TIMING_II_IS_1024x768x70HZ(timing2) timing2 & EDIDBIT2
  109. #define USER_TIMING_II_IS_1024x768x75HZ(timing2) timing2 & EDIDBIT1
  110. #define USER_TIMING_II_IS_1280x1024x75HZ(timing2) timing2 & EDIDBIT0
  111. // TIMING_III
  112. #define USER_TIMING_III_IS_1152x870x75HZ(timing3) timing3 & EDIDBIT7
  113. #define USER_TIMING_III_IS_RESERVED1(timing3) timing3 & EDIDBIT6
  114. #define USER_TIMING_III_IS_RESERVED2(timing3) timing3 & EDIDBIT5
  115. #define USER_TIMING_III_IS_RESERVED3(timing3) timing3 & EDIDBIT4
  116. #define USER_TIMING_III_IS_RESERVED4(timing3) timing3 & EDIDBIT3
  117. #define USER_TIMING_III_IS_RESERVED5(timing3) timing3 & EDIDBIT2
  118. #define USER_TIMING_III_IS_RESERVED6(timing3) timing3 & EDIDBIT1
  119. #define USER_TIMING_III_IS_RESERVED7(timing3) timing3 & EDIDBIT0
  120. //
  121. // Function Prototypes exposed,
  122. //
  123. typedef enum {
  124. Undefined,
  125. NonRGB,
  126. IsRGB,
  127. IsMonochrome
  128. } DISPLAY_TYPE, *PDISPLAY_TYPE;
  129. //
  130. // 0) Header Macros
  131. //
  132. #define GET_HEADER_BYTE(pEdid, x) pEdid->UC_Header[x]
  133. /////////////////////////////////////////////
  134. // 1) Oem_Identification macros
  135. //
  136. #define GET_EDID_OEM_ID_NAME(pEdid) \
  137. *(UNALIGNED USHORT *)(&(pEdid->UC_OemIdentification[0]))
  138. #define GET_EDID_OEM_PRODUCT_CODE(pEdid) \
  139. *(UNALIGNED USHORT *)(&(pEdid->UC_OemIdentification[2]))
  140. #define GET_EDID_OEM_SERIAL_NUMBER(pEdid) \
  141. *(UNALIGNED ULONG *)(&(pEdid->UC_OemIdentification[4]))
  142. #define GET_EDID_OEM_WEEK_MADE(pEdid) pEdid->UC_OemIdentification[8]
  143. #define GET_EDID_OEM_YEAR_MADE(pEdid) pEdid->UC_OemIdentification[9]
  144. /////////////////////////////////////////////
  145. // 2) EDID Version macros
  146. //
  147. #define GET_EDID_VERSION(pEdid) pEdid->UC_Version[0]
  148. #define GET_EDID_REVISION(pEdid) pEdid->UC_Version[1]
  149. /////////////////////////////////////////////
  150. // 3) EDID Basic Display Feature macros
  151. //
  152. #define GET_EDID_INPUT_DEFINITION(pEdid) pEdid->UC_BasicDisplayParameters[0]
  153. #define GET_EDID_MAX_X_IMAGE_SIZE(pEdid) pEdid->UC_BasicDisplayParameters[1]
  154. #define GET_EDID_MAX_Y_IMAGE_SIZE(pEdid) pEdid->UC_BasicDisplayParameters[2]
  155. #define GET_EDID_DISPLAY_XFER_CHAR(pEdid) pEdid->UC_BasicDisplayParameters[3]
  156. #define GET_EDID_FEATURE_SUPPORT(pEdid) pEdid->UC_BasicDisplayParameters[4]
  157. //
  158. // 3.1) INPUT_DEFINITION masks.
  159. //
  160. #define INPUT_DEF_PULSE_REQUIRED_SYNC_MASK EDIDBIT0
  161. #define INPUT_DEF_GREEN_SYNC_SUPORTED_MASK EDIDBIT1
  162. #define INPUT_DEF_COMPOSITE_SYNC_SUPORTED_MASK EDIDBIT2
  163. #define INPUT_DEF_SEPARATE_SYNC_SUPPORTED_MASK EDIDBIT3
  164. #define INPUT_DEF_SETUP_BLANK_TO_BLACK_MASK EDIDBIT4
  165. #define INPUT_DEF_SIGNAL_LEVEL_STANDARD_MASK (EDIDBIT5 | EDIDBIT6)
  166. #define INPUT_DEF_DIGITAL_LEVEL_MASK EDIDBIT7
  167. //
  168. // 3.1a) SIGNAL_LEVEL_STANDARD macros
  169. //
  170. typedef enum {
  171. POINT7_TO_POINT3,
  172. POINT714_TO_POINT286,
  173. ONE_TO_POINT4,
  174. POINT7_TO_0
  175. } SIGNAL_LEVEL, *PSIGNAL_LEVEL;
  176. #define SIGNAL_LEVEL_IS_POINT7_TO_POINT3 EDIDBITNONE
  177. #define SIGNAL_LEVEL_IS_POINT714_TO_POINT286 EDIDBIT5
  178. #define SIGNAL_LEVEL_IS_1_TO_POINT4 EDIDBIT6
  179. #define SIGNAL_LEVEL_IS_POINT7_TO_0 (EDIDBIT6 | EDIDBIT5)
  180. //
  181. // 3.2) Hoizontal IMAGE_SIZE is value of byte in centimeters.
  182. // 3.3) Vertical IMAGE_SIZE is value of byte in centimeters.
  183. //
  184. //
  185. // 3.4) XFER_CHARACTERISTIC is gamma*100 - 100, so invert in USER.
  186. // NOTE: This must be called from USER, so is in edid.h
  187. //
  188. //#define USER_CONVERT_TO_GAMMA(achar) \
  189. // (achar + 100)/100
  190. //
  191. // 3.5) FEATURE_SUPPORT masks
  192. //
  193. #define FEATURE_RESERVED_0_MASK EDIDBIT0
  194. #define FEATURE_RESERVED_1_MASK EDIDBIT1
  195. #define FEATURE_RESERVED_2_MASK EDIDBIT2
  196. #define FEATURE_DISPLAY_TYPE_MASK (EDIDBIT3|EDIDBIT4)
  197. #define FEATURE_ACTIVE_OFF_MASK EDIDBIT5
  198. #define FEATURE_SUSPEND_MASK EDIDBIT6
  199. #define FEATURE_STANDBY_MASK EDIDBIT7
  200. #define FEATURE_DISPLAY_TYPE_IS_UNDEFINED(x) \
  201. ((x)&FEATURE_DISPLAY_TYPE_MASK) == FEATURE_DISPLAY_TYPE_MASK
  202. #define FEATURE_DISPLAY_TYPE_IS_NON_RGB(x) \
  203. ((x)&FEATURE_DISPLAY_TYPE_MASK) == EDIDBIT4
  204. #define FEATURE_DISPLAY_TYPE_IS_RGB(x) \
  205. ((x)&FEATURE_DISPLAY_TYPE_MASK) == EDIDBIT3
  206. #define FEATURE_DISPLAY_TYPE_IS_MONOCHROME(x) \
  207. ((x)&FEATURE_DISPLAY_TYPE_MASK) == EDIDBITNONE
  208. //
  209. // Another copy of the data stucture for reference.
  210. //
  211. //
  212. // typedef struct _EDID {
  213. // UCHAR UC_Header[8];
  214. // UCHAR UC_OemIdentification[10];
  215. // UCHAR UC_Version[2];
  216. // UCHAR UC_BasicDisplayParameters[5];
  217. // UCHAR UC_ColorCharacteristics[10];
  218. // UCHAR UC_EstablishedTimings[3];
  219. // USHORT US_StandardTimingIdentifications[8];
  220. // UCHAR UC_Detail1[18];
  221. // UCHAR UC_Detail2[18];
  222. // UCHAR UC_Detail3[18];
  223. // UCHAR UC_Detail4[18];
  224. // UCHAR UC_ExtensionFlag;
  225. // UCHAR UC_CheckSum;
  226. // } EDID, *PEDID;
  227. //
  228. /////////////////////////////////////////////
  229. // 4) Color Characteristics - weird. The deal is that the first byte
  230. // in this array is the red and green low order bits. The next byte is
  231. // the blue and white low order bits. The remainder are the high order
  232. // bits of the colors.
  233. //
  234. #define GET_EDID_COLOR_CHAR_RG_LOW(pEdid) pEdid->UC_ColorCharacteristics[0]
  235. #define GET_EDID_COLOR_CHAR_RX_HIGH(pEdid) pEdid->UC_ColorCharacteristics[2]
  236. #define GET_EDID_COLOR_CHAR_RY_HIGH(pEdid) pEdid->UC_ColorCharacteristics[3]
  237. #define GET_EDID_COLOR_CHAR_GX_HIGH(pEdid) pEdid->UC_ColorCharacteristics[4]
  238. #define GET_EDID_COLOR_CHAR_GY_HIGH(pEdid) pEdid->UC_ColorCharacteristics[5]
  239. #define GET_RED_X_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  240. do { \
  241. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  242. lowbyte &= (EDIDBIT6 | EDIDBIT7); \
  243. highbyte = GET_EDID_COLOR_CHAR_RX_HIGH(pEdid); \
  244. } while (0)
  245. #define GET_RED_Y_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  246. do { \
  247. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  248. lowbyte &= (EDIDBIT4 | EDIDBIT5); \
  249. highbyte = GET_EDID_COLOR_CHAR_RY_HIGH(pEdid); \
  250. } while (0)
  251. #define GET_GREEN_X_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  252. do { \
  253. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  254. lowbyte &= (EDIDBIT2 | EDIDBIT3); \
  255. highbyte = GET_EDID_COLOR_CHAR_GX_HIGH(pEdid); \
  256. } while (0)
  257. #define GET_GREEN_Y_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  258. do { \
  259. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  260. lowbyte &= (EDIDBIT0 | EDIDBIT1); \
  261. highbyte = GET_EDID_COLOR_CHAR_GY_HIGH(pEdid); \
  262. } while (0)
  263. #define GET_EDID_COLOR_CHAR_BW_LOW(pEdid) pEdid->UC_ColorCharacteristics[1]
  264. #define GET_EDID_COLOR_CHAR_BX_HIGH(pEdid) pEdid->UC_ColorCharacteristics[6]
  265. #define GET_EDID_COLOR_CHAR_BY_HIGH(pEdid) pEdid->UC_ColorCharacteristics[7]
  266. #define GET_EDID_COLOR_CHAR_WX_HIGH(pEdid) pEdid->UC_ColorCharacteristics[8]
  267. #define GET_EDID_COLOR_CHAR_WY_HIGH(pEdid) pEdid->UC_ColorCharacteristics[9]
  268. #define GET_BLUE_X_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  269. do { \
  270. lowbyte = GET_EDID_COLOR_CHAR_BW_LOW(pEdid); \
  271. lowbyte &= (EDIDBIT6 | EDIDBIT7); \
  272. highbyte = GET_EDID_COLOR_CHAR_BX_HIGH(pEdid); \
  273. } while (0)
  274. #define GET_BLUE_Y_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  275. do { \
  276. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  277. lowbyte &= (EDIDBIT4 | EDIDBIT5); \
  278. highbyte = GET_EDID_COLOR_CHAR_BY_HIGH(pEdid); \
  279. } while (0)
  280. #define GET_WHITE_X_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  281. do { \
  282. lowbyte = GET_EDID_COLOR_CHAR_BW_LOW(pEdid); \
  283. lowbyte &= (EDIDBIT2 | EDIDBIT3); \
  284. highbyte = GET_EDID_COLOR_CHAR_WX_HIGH(pEdid); \
  285. } while (0)
  286. #define GET_WHITE_Y_COLOR_CHARS(pEdid, lowbyte, highbyte) \
  287. do { \
  288. lowbyte = GET_EDID_COLOR_CHAR_RG_LOW(pEdid); \
  289. lowbyte &= (EDIDBIT0 | EDIDBIT1); \
  290. highbyte = GET_EDID_COLOR_CHAR_WY_HIGH(pEdid); \
  291. } while (0)
  292. //
  293. // 4.1) Chromaticity Coordinates Format macro. Use these to convert
  294. // from the binary format to the actual decimal representation.
  295. // NOTE: can only be called from USER.
  296. //
  297. //
  298. //#define USER_CONVERT_CHROMATICITY_FROM_BINARY_TO_DECIMAL(ashort) \
  299. // (ashort & EDIDBIT9)*(1/2) + (ashort & EDIDBIT8)*(1/4) + \
  300. // (ashort & EDIDBIT7)*(1/8) + (ashort & EDIDBIT6)*(1/16) + \
  301. // (ashort & EDIDBIT5)*(1/32) + (ashort & EDIDBIT4)*(1/64) + \
  302. // (ashort & EDIDBIT3)*(1/128) + (ashort & EDIDBIT2)*(1/256) + \
  303. // (ashort & EDIDBIT1)*(1/512) + (ashort & EDIDBIT0)*(1/1024)
  304. //
  305. //
  306. // Another copy of the data stucture for reference.
  307. //
  308. //
  309. // typedef struct _EDID {
  310. // UCHAR UC_Header[8];
  311. // UCHAR UC_OemIdentification[10];
  312. // UCHAR UC_Version[2];
  313. // UCHAR UC_BasicDisplayParameters[5];
  314. // UCHAR UC_ColorCharacteristics[10];
  315. // UCHAR UC_EstablishedTimings[3];
  316. // USHORT US_StandardTimingIdentifications[8];
  317. // UCHAR UC_Detail1[18];
  318. // UCHAR UC_Detail2[18];
  319. // UCHAR UC_Detail3[18];
  320. // UCHAR UC_Detail4[18];
  321. // UCHAR UC_ExtensionFlag;
  322. // UCHAR UC_CheckSum;
  323. // } EDID, *PEDID;
  324. //
  325. /////////////////////////////////////////////
  326. // 5) Established Timings
  327. // These are bitfields indicating the types of timings supported.
  328. //
  329. #define GET_EDID_ESTABLISHED_TIMING_I(pEdid) pEdid->UC_EstablishedTimings[0]
  330. #define GET_EDID_ESTABLISHED_TIMING_II(pEdid) pEdid->UC_EstablishedTimings[1]
  331. #define GET_EDID_ESTABLISHED_TIMING_III(pEdid) pEdid->UC_EstablishedTimings[2]
  332. //
  333. // 5.1) Macros for USER to decode the bitfields
  334. // Also defined in edid.h
  335. //
  336. // TIMING_I
  337. // #define USER_TIMING_I_IS_720x400x70HZ(timing1) timing1 & EDIDBIT7
  338. // #define USER_TIMING_I_IS_720x400x88HZ(timing1) timing1 & EDIDBIT6
  339. // #define USER_TIMING_I_IS_640x480x60HZ(timing1) timing1 & EDIDBIT5
  340. // #define USER_TIMING_I_IS_640x480x67HZ(timing1) timing1 & EDIDBIT4
  341. // #define USER_TIMING_I_IS_640x480x72HZ(timing1) timing1 & EDIDBIT3
  342. // #define USER_TIMING_I_IS_640x480x75HZ(timing1) timing1 & EDIDBIT2
  343. // #define USER_TIMING_I_IS_800x600x56HZ(timing1) timing1 & EDIDBIT1
  344. // #define USER_TIMING_I_IS_800x600x60HZ(timing1) timing1 & EDIDBIT0
  345. //
  346. // // TIMING_II
  347. //
  348. // #define USER_TIMING_II_IS_800x600x72HZ(timing2) timing2 & EDIDBIT7
  349. // #define USER_TIMING_II_IS_800x600x75HZ(timing2) timing2 & EDIDBIT6
  350. // #define USER_TIMING_II_IS_832x624x75HZ(timing2) timing2 & EDIDBIT5 // MAC only
  351. // #define USER_TIMING_II_IS_1024x768x87HZ(timing2) timing2 & EDIDBIT4
  352. // #define USER_TIMING_II_IS_1024x768x60HZ(timing2) timing2 & EDIDBIT3
  353. // #define USER_TIMING_II_IS_1024x768x70HZ(timing2) timing2 & EDIDBIT2
  354. // #define USER_TIMING_II_IS_1024x768x75HZ(timing2) timing2 & EDIDBIT1
  355. // #define USER_TIMING_II_IS_1280x1024x75HZ(timing2) timing2 & EDIDBIT0
  356. //
  357. // TIMING_III
  358. //
  359. // #define USER_TIMING_III_IS_1152x870x75HZ(timing3) timing3 & EDIDBIT7 // MAC only
  360. // #define USER_TIMING_III_IS_RESERVED1(timing3) timing3 & EDIDBIT6
  361. // #define USER_TIMING_III_IS_RESERVED2(timing3) timing3 & EDIDBIT5
  362. // #define USER_TIMING_III_IS_RESERVED3(timing3) timing3 & EDIDBIT4
  363. // #define USER_TIMING_III_IS_RESERVED4(timing3) timing3 & EDIDBIT3
  364. // #define USER_TIMING_III_IS_RESERVED5(timing3) timing3 & EDIDBIT2
  365. // #define USER_TIMING_III_IS_RESERVED6(timing3) timing3 & EDIDBIT1
  366. // #define USER_TIMING_III_IS_RESERVED7(timing3) timing3 & EDIDBIT0
  367. //
  368. //
  369. // Another copy of the data stucture for reference.
  370. //
  371. //
  372. // typedef struct _EDID {
  373. // UCHAR UC_Header[8];
  374. // UCHAR UC_OemIdentification[10];
  375. // UCHAR UC_Version[2];
  376. // UCHAR UC_BasicDisplayParameters[5];
  377. // UCHAR UC_ColorCharacteristics[10];
  378. // UCHAR UC_EstablishedTimings[3];
  379. // USHORT US_StandardTimingIdentifications[8];
  380. // UCHAR UC_Detail1[18];
  381. // UCHAR UC_Detail2[18];
  382. // UCHAR UC_Detail3[18];
  383. // UCHAR UC_Detail4[18];
  384. // UCHAR UC_ExtensionFlag;
  385. // UCHAR UC_CheckSum;
  386. // } EDID, *PEDID;
  387. //
  388. /////////////////////////////////////////////
  389. // 6) Standard Timing Identifications
  390. //
  391. // Has horizontal (x) active pixel count as lower byte, refresh rate
  392. // as first 6 bits of upper byte and, image aspect ratio as remaining
  393. // two bits in upper byte.
  394. //
  395. // Get standard timing ids
  396. #define GET_EDID_STANDARD_TIMING_ID(pEdid, x) \
  397. pEdid->US_StandardTimingIdentifications[x]
  398. #define EDIDBIT14 0x4000
  399. #define EDIDBIT15 0x8000
  400. // Decode Horizontal active pixel range bits.
  401. #define GET_X_ACTIVE_PIXEL_RANGE(ushort) ((ushort&0xff)+ 31) * 8
  402. // Decode Aspect ratio bits.
  403. #define IS_ASPECT_RATIO_1_TO_1(ushort) \
  404. (!(ushort & EDIDBIT14) && !(ushort & EDIDBIT15))
  405. #define IS_ASPECT_RATIO_4_TO_3(ushort) \
  406. ((ushort & EDIDBIT14) && !(ushort & EDIDBIT15))
  407. #define IS_ASPECT_RATIO_5_TO_4(ushort) \
  408. (!(ushort & EDIDBIT14) && (ushort & EDIDBIT15))
  409. #define IS_ASPECT_RATIO_16_TO_9(ushort) \
  410. ((ushort & EDIDBIT14) && (ushort & EDIDBIT15))
  411. #define GET_HZ_REFRESH_RATE(ushort) \
  412. ((ushort & 0x3f) + 60)
  413. //
  414. // Another copy of the data stucture for reference.
  415. //
  416. //
  417. // typedef struct _EDID {
  418. // UCHAR UC_Header[8];
  419. // UCHAR UC_OemIdentification[10];
  420. // UCHAR UC_Version[2];
  421. // UCHAR UC_BasicDisplayParameters[5];
  422. // UCHAR UC_ColorCharacteristics[10];
  423. // UCHAR UC_EstablishedTimings[3];
  424. // USHORT US_StandardTimingIdentifications[8];
  425. // UCHAR UC_Detail1[18];
  426. // UCHAR UC_Detail2[18];
  427. // UCHAR UC_Detail3[18];
  428. // UCHAR UC_Detail4[18];
  429. // UCHAR UC_ExtensionFlag;
  430. // UCHAR UC_CheckSum;
  431. // } EDID, *PEDID;
  432. //
  433. /////////////////////////////////////////////
  434. // 7) Detailed Timing Description
  435. //
  436. // Too ugly for words. See macros. Note that these fields in
  437. // the EDID can either be these data structures or a monitor
  438. // description data structure. If the first two bytes are 0x0000
  439. // then it's a monitor descriptor.
  440. //
  441. //
  442. //
  443. #define GET_EDID_PDETAIL1(pEdid) &(pEdid->UC_Detail1)
  444. #define GET_EDID_PDETAIL2(pEdid) &(pEdid->UC_Detail2)
  445. #define GET_EDID_PDETAIL3(pEdid) &(pEdid->UC_Detail3)
  446. #define GET_EDID_PDETAIL4(pEdid) &(pEdid->UC_Detail4)
  447. typedef struct __DETAILED_TIMING_DESCRIPTION {
  448. UCHAR PixelClock[2];
  449. UCHAR XLowerActive;
  450. UCHAR XLowerBlanking;
  451. UCHAR XUpper;
  452. UCHAR YLowerActive;
  453. UCHAR YLowerBlanking;
  454. UCHAR YUpper;
  455. UCHAR XLowerSyncOffset;
  456. UCHAR XLowerSyncPulseWidth;
  457. UCHAR YLowerSyncOffsetLowerPulseWidth;
  458. UCHAR XSyncOffsetPulseWidth_YSyncOffsetPulseWidth;
  459. UCHAR XSizemm;
  460. UCHAR YSizemm;
  461. UCHAR XYSizemm;
  462. UCHAR XBorderpxl;
  463. UCHAR YBorderpxl;
  464. UCHAR Flags;
  465. } DETAILED_TIMING_DESCRIPTION, *PDETAILED_TIMING_DESCRIPTION;
  466. #define GET_DETAIL_PIXEL_CLOCK(pDetail, ushort) \
  467. do { \
  468. ushort = pDetail->PixelClock[0]; \
  469. ushort <<= 8; \
  470. ushort |= pDetail->PixelClock[1]; \
  471. } while (0)
  472. #define GET_DETAIL_X_ACTIVE(pDetailedTimingDesc, ushort)\
  473. do { \
  474. ushort = pDetailedTimingDesc->XUpper; \
  475. ushort &= 0xf0; \
  476. ushort <<= 4; \
  477. ushort |= pDetailedTimingDesc->XLowerActive; \
  478. } while (0)
  479. #define GET_DETAIL_X_BLANKING(pDetailedTimingDesc, ushort) \
  480. do { \
  481. ushort = pDetailedTimingDesc->XUpper; \
  482. ushort &= 0xf; \
  483. ushort <<= 8; \
  484. ushort |= pDetailedTimingDesc->XLowerBlanking;\
  485. } while (0)
  486. #define GET_DETAIL_Y_ACTIVE(pDetailedTimingDesc, ushort)\
  487. do { \
  488. ushort = pDetailedTimingDesc->YUpper; \
  489. ushort &= 0xf0; \
  490. ushort <<= 4; \
  491. ushort |= pDetailedTimingDesc->YLowerActive; \
  492. } while (0)
  493. #define GET_DETAIL_Y_BLANKING(pDetailedTimingDesc, ushort) \
  494. do { \
  495. ushort = pDetailedTimingDesc->YUpper; \
  496. ushort &= 0xf; \
  497. ushort <<= 8; \
  498. ushort |= pDetailedTimingDesc->YLowerBlanking;\
  499. } while (0)
  500. #define GET_DETAIL_X_SYNC_OFFSET(pDetailedTimingDesc, ushort) \
  501. do { \
  502. ushort = pDetailedTimingDesc->XSyncOffsetPulseWidth_YSyncOffsetPulseWidth; \
  503. ushort >>= 6; \
  504. ushort <<= 8; \
  505. ushort |= pDetailedTimingDesc->XLowerSyncOffset; \
  506. } while (0)
  507. #define GET_DETAIL_X_SYNC_PULSEWIDTH(pDetailedTimingDesc, ushort) \
  508. do { \
  509. ushort = pDetailedTimingDesc->XSyncOffsetPulseWidth_YSyncOffsetPulseWidth; \
  510. ushort >>= 4; \
  511. ushort &= (EDIDBIT0|EDIDBIT1); \
  512. ushort <<= 8; \
  513. ushort |= pDetailedTimingDesc->XLowerSyncPulseWidth; \
  514. } while (0)
  515. #define GET_DETAIL_Y_SYNC_OFFSET(pDetailedTimingDesc, ushort) \
  516. do { \
  517. ushort = pDetailedTimingDesc->XSyncOffsetPulseWidth_YSyncOffsetPulseWidth; \
  518. ushort >>= 2; \
  519. ushort &= (EDIDBIT0|EDIDBIT1); \
  520. ushort <<= 12; \
  521. ushort |= pDetailedTimingDesc->YLowerSyncOffsetLowerPulseWidth;\
  522. ushort >>= 4; \
  523. } while (0)
  524. #define GET_DETAIL_Y_SYNC_PULSEWIDTH(pDetailedTimingDesc, ushort) \
  525. do { \
  526. ushort = pDetailedTimingDesc->XSyncOffsetPulseWidth_YSyncOffsetPulseWidth; \
  527. ushort &= (EDIDBIT0|EDIDBIT1); \
  528. ushort <<= 8; \
  529. ushort |= (pDetailedTimingDesc->YLowerSyncOffsetLowerPulseWidth & 0xf); \
  530. } while (0)
  531. #define GET_DETAIL_X_SIZE_MM(pDetailedTimingDesc, ushort) \
  532. do { \
  533. ushort |= pDetailedTimingDesc->XYSizemm; \
  534. ushort >>= 4; \
  535. ushort <<= 8; \
  536. ushort |= pDetailedTimingDesc->XSizemm; \
  537. } while (0)
  538. #define GET_DETAIL_Y_SIZE_MM(pDetailedTimingDesc, ushort) \
  539. do { \
  540. ushort |= pDetailedTimingDesc->XYSizemm; \
  541. ushort &= 0xf; \
  542. ushort <<= 8; \
  543. ushort |= pDetailedTimingDesc->YSizemm; \
  544. } while (0)
  545. #define GET_DETAIL_TIMING_DESC_FLAG(pDetailedTimingDesc) \
  546. pDetailedTimingDesc->Flags
  547. #define IS_DETAIL_FLAGS_INTERLACED(Flags) Flags & EDIDBIT7
  548. #define IS_DETAIL_FLAGS_FIELD_SEQ_STEREO_RIGHT(Flags) \
  549. (!(Flags & EDIDBIT0) && (Flags & EDIDBIT5) && !(Flags & EDIDBIT6))
  550. #define IS_DETAIL_FLAGS_FIELD_SEQ_STEREO_LEFT(Flags) \
  551. (!(Flags & EDIDBIT0) && !(Flags & EDIDBIT5) && (Flags & EDIDBIT6))
  552. #define IS_DETAIL_FLAGS_STEREO_RIGHT_EVEN(Flags) \
  553. ((Flags & EDIDBIT0) && (Flags & EDIDBIT5) && !(Flags & EDIDBIT6))
  554. #define IS_DETAIL_FLAGS_STEREO_LEFT_EVEN(Flags) \
  555. ((Flags & EDIDBIT0) && !(Flags & EDIDBIT5) && (Flags & EDIDBIT6))
  556. #define IS_DETAIL_FLAGS_STEREO_INTERLEAVED(Flags) \
  557. (!(Flags & EDIDBIT0) && (Flags & EDIDBIT5) && (Flags & EDIDBIT6))
  558. #define IS_DETAIL_FLAGS_SIDE_BY_SIDE(Flags) \
  559. ((Flags & EDIDBIT0) && (Flags & EDIDBIT5) && (Flags & EDIDBIT6))
  560. #define IS_DETAIL_FLAGS_ANALOGUE_COMPOSITE(Flags) \
  561. (!(Flags & EDIDBIT4) && !(Flags & EDIDBIT3))
  562. #define IS_DETAIL_FLAGS_BIPOLAR_ANALOGUE_COMPOSITE(Flags) \
  563. (!(Flags & EDIDBIT4) && (Flags & EDIDBIT3))
  564. #define IS_DETAIL_FLAGS_DIGITAL_COMPOSITE(Flags) \
  565. ((Flags & EDIDBIT4) && !(Flags & EDIDBIT3))
  566. #define IS_DETAIL_FLAGS_DIGITAL_SEPARATE(Flags) \
  567. ((Flags & EDIDBIT4) && (Flags & EDIDBIT3))
  568. #define IS_DETAIL_FLAGS_SYNC_ON_ALL_3_LINES(Flags) \
  569. ((IS_DETAIL_FLAGS_ANALOGUE_COMPOSITE(Flags) || \
  570. IS_DETAIL_FLAGS_BIPOLAR_ANALOGUE_COMPOSITE(Flags)) && \
  571. (Flags & EDIDBIT1))
  572. #define IS_DETAIL_FLAGS_COMPOSITE_POLARITY(Flags) \
  573. (IS_DETAIL_FLAGS_DIGITAL_COMPOSITE(Flags) && (Flags & EDIDBIT1))
  574. #define IS_DETAIL_FLAGS_HSYNC_POLARITY(Flags) \
  575. (IS_DETAIL_FLAGS_DIGITAL_SEPARATE(Flags) && (Flags & EDIDBIT1))
  576. typedef struct __MONITOR_DESCRIPTION {
  577. UCHAR Flag1[2];
  578. UCHAR ReservedFlag;
  579. UCHAR DataTypeFlag;
  580. UCHAR Flag2;
  581. UCHAR MonitorSNorData[13];
  582. } MONITOR_DESCRIPTION, *PMONITOR_DESCRIPTION;
  583. #define IS_MONITOR_DESCRIPTOR(pMonitorDesc) \
  584. (((pMonitorDesc->Flag1[0]) == 0) && ((pMonitorDesc->Flag1[1]) == 0))
  585. #define IS_MONITOR_DATA_SN(pMonitorDesc) \
  586. (pMonitorDesc->DataTypeFlag == 0xff)
  587. #define IS_MONITOR_DATA_STRING(pMonitorDesc) \
  588. (pMonitorDesc->DataTypeFlag == 0xfe)
  589. #define IS_MONITOR_RANGE_LIMITS(pMonitorDesc) \
  590. (pMonitorDesc->DataTypeFlag == 0xfd)
  591. #define IS_MONITOR_DATA_NAME(pMonitorDesc) \
  592. (pMonitorDesc->DataTypeFlag == 0xfc)
  593. #define GET_MONITOR_RANGE_LIMITS(pMonitorDesc) \
  594. pMonitorDesc->MonitorSNorData
  595. #define GET_RANGE_LIMIT_MIN_Y_RATE(pMonitorSNorData) \
  596. pMonitorSNorData[5]
  597. #define GET_RANGE_LIMIT_MAX_Y_RATE(pMonitorSNorData) \
  598. pMonitorSNorData[6]
  599. #define GET_RANGE_LIMIT_MIN_X_RATE(pMonitorSNorData) \
  600. pMonitorSNorData[7]
  601. #define GET_RANGE_LIMIT_MAX_X_RATE(pMonitorSNorData) \
  602. pMonitorSNorData[8]
  603. // This is really rate/10!
  604. //
  605. #define GET_RANGE_LIMIT_MAX_PIXELCLOCK_RATE(pMonitorSNorData) \
  606. pMonitorSNorData[9]
  607. #define GET_RANGE_LIMIT_PGTF(pMonitorSNorData) \
  608. &pMonitorSNorData[10]
  609. #define IS_MONITOR_DATA_COLOR_INFO(pMonitorDesc) \
  610. (pMonitorDesc->DataTypeFlag == 0xfb)
  611. //
  612. // More macros defined in edid.h
  613. //
  614. //#define USER_GET_COLOR_INFO_W1POINT_INDEX(pMonitorSNorData) \
  615. // pMonitorSNorData[0]
  616. //
  617. //#define USER_GET_COLOR_INFO_W1_LOWBITS(pMonitorSNorData) \
  618. // pMonitorSNorData[1]
  619. //
  620. //#define USER_GET_COLOR_INFO_W1_X(pMonitorSNorData) \
  621. // pMonitorSNorData[2]
  622. //
  623. //#define USER_GET_COLOR_INFO_W1_Y(pMonitorSNorData) \
  624. // pMonitorSNorData[3]
  625. //
  626. //#define USER_GET_COLOR_INFO_W1_GAMMA(pMonitorSNorData) \
  627. // pMonitorSNorData[4]
  628. //
  629. //#define USER_GET_COLOR_INFO_W2POINT_INDEX(pMonitorSNorData) \
  630. // pMonitorSNorData[5]
  631. //
  632. //#define USER_GET_COLOR_INFO_W2_LOWBITS(pMonitorSNorData) \
  633. // pMonitorSNorData[6]
  634. //#define USER_GET_COLOR_INFO_W2_X(pMonitorSNorData) \
  635. // pMonitorSNorData[7]
  636. //
  637. //#define USER_GET_COLOR_INFO_W2_Y(pMonitorSNorData) \
  638. // pMonitorSNorData[8]
  639. //
  640. //#define USER_GET_COLOR_INFO_W2_GAMMA(pMonitorSNorData) \
  641. // pMonitorSNorData[9]
  642. //
  643. //
  644. #define IS_MONITOR_DATA_TIMING_ID(pMonitorDesc) \
  645. (pMonitorDesc->DataTypeFlag == 0xfa)
  646. typedef union __MONITOR_OR_DETAIL {
  647. MONITOR_DESCRIPTION MonitorDescription;
  648. DETAILED_TIMING_DESCRIPTION DetailedTimingDescription;
  649. } MONITOR_OR_DETAIL, *PMONITOR_OR_DETAIL;
  650. /////////////////////////////////////////////
  651. // 8) Extension Flag
  652. //
  653. // Number of optional 128 byte EDID extension blocks to follow.
  654. //
  655. #define GET_EDID_EXTENSION_FLAG(pEdid) pEdid->UC_ExtensionFlag
  656. /////////////////////////////////////////////
  657. // 9) Checksum
  658. //
  659. //
  660. #define GET_EDID_CHECKSUM(pEdid) pEdid->UC_Checksum
  661. BOOLEAN
  662. EdidCheckSum(
  663. IN PCHAR pBlob,
  664. IN ULONG BlobSize
  665. );