diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c new file mode 100644 index 0000000..d434f2f --- /dev/null +++ b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c | |||
@@ -0,0 +1,457 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Red Hat, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * on the rights to use, copy, modify, merge, publish, distribute, sub | ||
8 | * license, and/or sell copies of the Software, and to permit persons to whom | ||
9 | * the Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | /* Original Author: Adam Jackson <ajax@nwnk.net> */ | ||
23 | /* Heavily modified by: Leif Middelschulte <leif.middelschulte@gmail.com> */ | ||
24 | |||
25 | #include "Ecore_X.h" | ||
26 | |||
27 | /* TODO: | ||
28 | * - see other TODO's within this file. | ||
29 | */ | ||
30 | |||
31 | #define ECORE_X_RANDR_EDID_VERSION_10 ((1 << 8) | 0) | ||
32 | #define ECORE_X_RANDR_EDID_VERSION_11 ((1 << 8) | 1) | ||
33 | #define ECORE_X_RANDR_EDID_VERSION_12 ((1 << 8) | 2) | ||
34 | #define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) | ||
35 | #define ECORE_X_RANDR_EDID_VERSION_14 ((1 << 8) | 4) | ||
36 | |||
37 | #define _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER 0x08 | ||
38 | #define _ECORE_X_RANDR_EDID_OFFSET_TYPE 0x14 | ||
39 | #define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 | ||
40 | #define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 | ||
41 | #define _ECORE_X_RANDR_EDID_OFFSET_DPMS 0x18 | ||
42 | #define _ECORE_X_RANDR_EDID_OFFSET_COLORSPACE 0x18 | ||
43 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 | ||
44 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 | ||
45 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 | ||
46 | #define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED 15 | ||
47 | #define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO 14 | ||
48 | |||
49 | #define _ECORE_X_RANDR_EDID_MASK_DIGITAL 0x80 | ||
50 | #define _ECORE_X_RANDR_EDID_MASK_DIGITAL_INTERFACE 0x0f | ||
51 | #define _ECORE_X_RANDR_EDID_MASK_DIGITAL_TMDS_DFP_10 0x01 | ||
52 | #define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS 0x18 | ||
53 | #define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444 0x10 | ||
54 | #define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422 0x08 | ||
55 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED 0xe0 | ||
56 | #define _ECORE_X_RANDR_EDID_MASK_DPMS 0xE0 | ||
57 | #define _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY 0x80 | ||
58 | #define _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND 0x40 | ||
59 | #define _ECORE_X_RANDR_EDID_MASK_DPMS_OFF 0x20 | ||
60 | #define _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE 0x0f | ||
61 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3 0x80 | ||
62 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9 0x40 | ||
63 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10 0x20 | ||
64 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4 0x10 | ||
65 | #define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9 0x08 | ||
66 | |||
67 | #define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 | ||
68 | |||
69 | typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred { | ||
70 | ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00, | ||
71 | ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01, | ||
72 | ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02, | ||
73 | ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03, | ||
74 | ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04 | ||
75 | } Ecore_X_Randr_Edid_Aspect_Ratio_Preferred; | ||
76 | |||
77 | /* Some convenience loops */ | ||
78 | #define _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, extension_block_iter) \ | ||
79 | for (extension_block_iter = edid; extension_block_iter < (edid + edid_length); extension_block_iter += 128) | ||
80 | |||
81 | #define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ | ||
82 | _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, cea_block_iter) \ | ||
83 | if (cea_block_iter[0] == 0x02) | ||
84 | |||
85 | /* The following macro is to be used with caution as it inherits another loop. | ||
86 | * Therefore using a 'break;' statement will lead to continuation in the | ||
87 | * inherent 'Extension block'-loop. | ||
88 | */ | ||
89 | #define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_DETAILED_BLOCK(edid, edid_length, cea_block_iter, detailed_block_iter) \ | ||
90 | _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ | ||
91 | for (detailed_block_iter = cea_block_iter + cea_block_iter[2]; detailed_block_iter + 18 < cea_block_iter + 127; detailed_block_iter += 18) \ | ||
92 | if (detailed_block_iter[0]) | ||
93 | |||
94 | #define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ | ||
95 | for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) | ||
96 | |||
97 | #define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ | ||
98 | _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ | ||
99 | if ((block[0] == 0) && (block[1] == 0)) | ||
100 | |||
101 | EAPI Eina_Bool | ||
102 | ecore_x_randr_edid_has_valid_header(unsigned char *edid, | ||
103 | unsigned long edid_length) | ||
104 | { | ||
105 | const unsigned char header[] = | ||
106 | { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; | ||
107 | if (!edid) return EINA_FALSE; | ||
108 | if (edid_length < 8) return EINA_FALSE; | ||
109 | if (!memcmp(edid, header, 8)) return EINA_TRUE; | ||
110 | return EINA_FALSE; | ||
111 | } | ||
112 | |||
113 | EAPI int | ||
114 | ecore_x_randr_edid_version_get(unsigned char *edid, | ||
115 | unsigned long edid_length) | ||
116 | { | ||
117 | if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && | ||
118 | (ecore_x_randr_edid_has_valid_header(edid, edid_length))) | ||
119 | return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | | ||
120 | edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; | ||
121 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
122 | } | ||
123 | |||
124 | EAPI int | ||
125 | ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, | ||
126 | unsigned long edid_length) | ||
127 | { | ||
128 | if ((edid_length > 0x0b) && | ||
129 | (ecore_x_randr_edid_has_valid_header(edid, edid_length))) | ||
130 | return (int)(edid[0x0a] + (edid[0x0b] << 8)); | ||
131 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
132 | } | ||
133 | |||
134 | EAPI int | ||
135 | ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, | ||
136 | unsigned long edid_length) | ||
137 | { | ||
138 | if ((edid_length > 0x0f) && | ||
139 | (ecore_x_randr_edid_has_valid_header(edid, edid_length))) | ||
140 | return (int)(edid[0x0c] + (edid[0x0d] << 8) + | ||
141 | (edid[0x0e] << 16) + (edid[0x0f] << 24)); | ||
142 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
143 | } | ||
144 | |||
145 | EAPI char * | ||
146 | ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, | ||
147 | unsigned long edid_length) | ||
148 | { | ||
149 | if ((edid_length > (_ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER + 1)) && | ||
150 | (ecore_x_randr_edid_has_valid_header(edid, edid_length))) | ||
151 | { | ||
152 | unsigned char *x; | ||
153 | char *name; | ||
154 | |||
155 | x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER); | ||
156 | name = malloc(sizeof(char) * 4); | ||
157 | if (!name) return NULL; | ||
158 | name[0] = ((x[0] & 0x7c) >> 2) + '@'; | ||
159 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@'; | ||
160 | name[2] = (x[1] & 0x1f) + '@'; | ||
161 | name[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] = 0; | ||
162 | return name; | ||
163 | } | ||
164 | return NULL; | ||
165 | } | ||
166 | |||
167 | EAPI char * | ||
168 | ecore_x_randr_edid_display_name_get(unsigned char *edid, | ||
169 | unsigned long edid_length) | ||
170 | { | ||
171 | unsigned char *block = NULL; | ||
172 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
173 | |||
174 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; | ||
175 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
176 | { | ||
177 | if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) | ||
178 | { | ||
179 | char *name, *p; | ||
180 | const char *edid_name; | ||
181 | |||
182 | edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; | ||
183 | name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); | ||
184 | if (!name) return NULL; | ||
185 | strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); | ||
186 | name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; | ||
187 | for (p = name; *p; p++) | ||
188 | { | ||
189 | if ((*p < ' ') || (*p > '~')) *p = 0; | ||
190 | } | ||
191 | return name; | ||
192 | } | ||
193 | } | ||
194 | return NULL; | ||
195 | } | ||
196 | |||
197 | EAPI Ecore_X_Randr_Edid_Aspect_Ratio | ||
198 | ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, | ||
199 | unsigned long edid_length) | ||
200 | { | ||
201 | unsigned char *block = NULL; | ||
202 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
203 | |||
204 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
205 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
206 | { | ||
207 | if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && | ||
208 | (block[10] == 0x04)) | ||
209 | { | ||
210 | Ecore_X_Randr_Edid_Aspect_Ratio_Preferred preferred_ratio = | ||
211 | (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred) | ||
212 | ((block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED] & | ||
213 | _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED) >> 5); | ||
214 | switch (preferred_ratio) | ||
215 | { | ||
216 | case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3: | ||
217 | return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; | ||
218 | |||
219 | case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9: | ||
220 | return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; | ||
221 | |||
222 | case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10: | ||
223 | return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; | ||
224 | |||
225 | case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4: | ||
226 | return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; | ||
227 | |||
228 | case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9: | ||
229 | return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; | ||
230 | |||
231 | default: | ||
232 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
237 | } | ||
238 | |||
239 | EAPI Ecore_X_Randr_Edid_Aspect_Ratio | ||
240 | ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, | ||
241 | unsigned long edid_length) | ||
242 | { | ||
243 | Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
244 | unsigned char *block = NULL; | ||
245 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
246 | |||
247 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
248 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
249 | { | ||
250 | if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && | ||
251 | (block[10] == 0x04)) | ||
252 | { | ||
253 | if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3) | ||
254 | ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; | ||
255 | if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9) | ||
256 | ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; | ||
257 | if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10) | ||
258 | ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; | ||
259 | if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4) | ||
260 | ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; | ||
261 | if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9) | ||
262 | ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; | ||
263 | } | ||
264 | } | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | EAPI char * | ||
269 | ecore_x_randr_edid_display_ascii_get(unsigned char *edid, | ||
270 | unsigned long edid_length) | ||
271 | { | ||
272 | unsigned char *block = NULL; | ||
273 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
274 | |||
275 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; | ||
276 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
277 | { | ||
278 | if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfe) | ||
279 | { | ||
280 | char *ascii, *p; | ||
281 | const char *edid_ascii = (const char *)block + | ||
282 | _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; | ||
283 | /* | ||
284 | * TODO: Two of these in a row, in the third and fourth slots, | ||
285 | * seems to be specified by SPWG: http://www.spwg.org/ | ||
286 | */ | ||
287 | ascii = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); | ||
288 | if (!ascii) return NULL; | ||
289 | strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); | ||
290 | ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; | ||
291 | for (p = ascii; *p; p++) | ||
292 | { | ||
293 | if ((*p < ' ') || (*p > '~')) *p = 0; | ||
294 | } | ||
295 | return ascii; | ||
296 | } | ||
297 | } | ||
298 | return NULL; | ||
299 | } | ||
300 | |||
301 | EAPI char * | ||
302 | ecore_x_randr_edid_display_serial_get(unsigned char *edid, | ||
303 | unsigned long edid_length) | ||
304 | { | ||
305 | unsigned char *block = NULL; | ||
306 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
307 | |||
308 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; | ||
309 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
310 | { | ||
311 | if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xff) | ||
312 | { | ||
313 | char *serial, *p; | ||
314 | const char *edid_serial = (const char *)block + | ||
315 | _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; | ||
316 | /* | ||
317 | * TODO: Two of these in a row, in the third and fourth slots, | ||
318 | * seems to be specified by SPWG: http://www.spwg.org/ | ||
319 | */ | ||
320 | serial = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); | ||
321 | if (!serial) return NULL; | ||
322 | strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); | ||
323 | serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; | ||
324 | for (p = serial; *p; p++) | ||
325 | { | ||
326 | if ((*p < ' ') || (*p > '~')) *p = 0; | ||
327 | } | ||
328 | return serial; | ||
329 | } | ||
330 | } | ||
331 | return NULL; | ||
332 | } | ||
333 | |||
334 | EAPI Eina_Bool | ||
335 | ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, | ||
336 | unsigned long edid_length) | ||
337 | { | ||
338 | unsigned char *cea_block_iter = NULL; | ||
339 | char sum = 0; | ||
340 | int i; | ||
341 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
342 | |||
343 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
344 | if (edid_length < 128) return EINA_FALSE; | ||
345 | |||
346 | /* Check the EDID block itself */ | ||
347 | for (i = 0; i < 128; i++) sum += edid[i]; | ||
348 | if (sum) return EINA_FALSE; | ||
349 | |||
350 | /* Check the cea extension blocks */ | ||
351 | _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) | ||
352 | { | ||
353 | for (i = 0, sum = 0; i < 128; i++) sum += cea_block_iter[i]; | ||
354 | } | ||
355 | if (sum) return EINA_FALSE; | ||
356 | return EINA_TRUE; | ||
357 | } | ||
358 | |||
359 | EAPI Eina_Bool | ||
360 | ecore_x_randr_edid_dpms_available_get(unsigned char *edid, | ||
361 | unsigned long edid_length) | ||
362 | { | ||
363 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
364 | |||
365 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
366 | return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & | ||
367 | _ECORE_X_RANDR_EDID_MASK_DPMS); | ||
368 | } | ||
369 | |||
370 | EAPI Eina_Bool | ||
371 | ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, | ||
372 | unsigned long edid_length) | ||
373 | { | ||
374 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
375 | |||
376 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
377 | if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) | ||
378 | return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & | ||
379 | _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY); | ||
380 | return EINA_FALSE; | ||
381 | } | ||
382 | |||
383 | EAPI Eina_Bool | ||
384 | ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, | ||
385 | unsigned long edid_length) | ||
386 | { | ||
387 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
388 | |||
389 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
390 | if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) | ||
391 | return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & | ||
392 | _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND); | ||
393 | return EINA_FALSE; | ||
394 | } | ||
395 | |||
396 | EAPI Eina_Bool | ||
397 | ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, | ||
398 | unsigned long edid_length) | ||
399 | { | ||
400 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
401 | |||
402 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
403 | if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) | ||
404 | return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & | ||
405 | _ECORE_X_RANDR_EDID_MASK_DPMS_OFF); | ||
406 | return EINA_FALSE; | ||
407 | } | ||
408 | |||
409 | EAPI Eina_Bool | ||
410 | ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, | ||
411 | unsigned long edid_length) | ||
412 | { | ||
413 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
414 | |||
415 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; | ||
416 | return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & | ||
417 | _ECORE_X_RANDR_EDID_MASK_DIGITAL); | ||
418 | } | ||
419 | |||
420 | EAPI Ecore_X_Randr_Edid_Display_Colorscheme | ||
421 | ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, | ||
422 | unsigned long edid_length) | ||
423 | { | ||
424 | Ecore_X_Randr_Edid_Display_Colorscheme colorscheme = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
425 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
426 | |||
427 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return colorscheme; | ||
428 | if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length)) | ||
429 | { | ||
430 | colorscheme = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4; | ||
431 | if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & | ||
432 | _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444) | ||
433 | colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4; | ||
434 | if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & | ||
435 | _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422) | ||
436 | colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2; | ||
437 | } | ||
438 | else | ||
439 | colorscheme = edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS; | ||
440 | return colorscheme; | ||
441 | } | ||
442 | |||
443 | EAPI Ecore_X_Randr_Edid_Display_Interface_Type | ||
444 | ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, | ||
445 | unsigned long edid_length) | ||
446 | { | ||
447 | Ecore_X_Randr_Edid_Display_Interface_Type type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
448 | int version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
449 | |||
450 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return type; | ||
451 | type = edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & | ||
452 | _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE; | ||
453 | if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT) | ||
454 | type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
455 | return type; | ||
456 | } | ||
457 | |||