Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/libsaio/edid.c

Source at commit 444 created 13 years 10 months ago.
By zef, Fixed calling getBootVolumeDescription() with properly adjusted strMaxLen values. Removed broken optionKey setting. Now using strncat() for adding proper NULL termination in destination strings.
1/*
2 * edid.c
3 *
4 *
5 * Created by Evan Lojewski on 12/1/09.
6 * Copyright 2009. All rights reserved.
7 *
8 */
9
10
11#include "libsaio.h"
12#include "edid.h"
13#include "vbe.h"
14#include "graphics.h"
15#include "boot.h"
16
17void getResolution(UInt32* x, UInt32* y, UInt32* bp)
18{
19int val;
20static UInt32 xResolution, yResolution, bpResolution;
21
22if(getIntForKey(kScreenWidth, &val, &bootInfo->bootConfig))
23{
24xResolution = val;
25}
26
27if(getIntForKey(kScreenHeight, &val, &bootInfo->bootConfig))
28{
29yResolution = val;
30}
31
32bpResolution = 32;// assume 32bits
33
34
35if(!xResolution || !yResolution || !bpResolution)
36{
37
38char* edidInfo = readEDID();
39
40if(!edidInfo) return;
41
42// TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that)
43xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
44yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
45
46//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );
47//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );
48
49free( edidInfo );
50
51if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;
52if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;
53
54}
55
56*x = xResolution;
57*y = yResolution;
58*bp = bpResolution;
59
60}
61
62char* readEDID()
63{
64SInt16 last_reported = -1;
65UInt8 edidInfo[EDID_BLOCK_SIZE];
66
67UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
68UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
69
70SInt16 status;
71UInt16 blocks_left = 1;
72
73do
74{
75// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
76
77bzero( edidInfo, EDID_BLOCK_SIZE);
78
79status = getEDID(edidInfo, blocks_left);
80
81
82//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
83/*
84int j, i;
85for (j = 0; j < 8; j++) {
86for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
87
88}
89printf("\n");
90*/
91
92if(status == 0)
93{
94//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
95if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
96 (memcmp(edidInfo, header2, sizeof(header2)) != 0) )
97{
98blocks_left--;
99int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
100
101if ( reported > blocks_left )
102{
103
104printf("EDID claims %d more blocks left\n", reported);
105}
106
107if ( (last_reported <= reported && last_reported != -1)
108|| reported == 0xff
109/* 0xff frequently comes up in corrupt edids */
110//|| reported == MAGIC
111)
112{
113printf("Last reported %d\n", last_reported);
114printf( "EDID blocks left is wrong.\n"
115 "Your EDID is probably invalid.\n");
116return 0;
117}
118else
119{
120//printf("Reading EDID block\n");
121//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );
122//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );
123
124last_reported = reported;
125blocks_left = reported;
126}
127}
128else
129{
130printf("Invalid block %d\n", blocks_left);
131printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
132printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
133return 0;
134}
135}
136blocks_left = 0;
137} while(blocks_left);
138
139char* ret = malloc(sizeof(edidInfo));
140memcpy(ret, edidInfo, sizeof(edidInfo));
141return ret;
142}
143

Archive Download this file

Revision: 444