Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/modules/Resolution/edid.c

Source at commit 1146 created 12 years 10 months ago.
By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing).
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: 1146