aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c457
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
69typedef 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
101EAPI Eina_Bool
102ecore_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
113EAPI int
114ecore_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
124EAPI int
125ecore_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
134EAPI int
135ecore_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
145EAPI char *
146ecore_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
167EAPI char *
168ecore_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
197EAPI Ecore_X_Randr_Edid_Aspect_Ratio
198ecore_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
239EAPI Ecore_X_Randr_Edid_Aspect_Ratio
240ecore_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
268EAPI char *
269ecore_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
301EAPI char *
302ecore_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
334EAPI Eina_Bool
335ecore_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
359EAPI Eina_Bool
360ecore_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
370EAPI Eina_Bool
371ecore_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
383EAPI Eina_Bool
384ecore_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
396EAPI Eina_Bool
397ecore_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
409EAPI Eina_Bool
410ecore_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
420EAPI Ecore_X_Randr_Edid_Display_Colorscheme
421ecore_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
443EAPI Ecore_X_Randr_Edid_Display_Interface_Type
444ecore_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