1/*
2	Author:
3	Rudolf Cornelissen 7/2004-08/2009
4*/
5
6#define MODULE_BIT 0x04000000
7
8#include "acc_std.h"
9
10/* Get some info about the device */
11status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info * adi)
12{
13	LOG(4,("GET_ACCELERANT_DEVICE_INFO: returning info\n"));
14
15	/* no info on version is provided, so presumably this is for my info */
16	adi->version = 1;
17
18	strcpy(adi->name, si->adi.name);
19	strcpy(adi->chipset, si->adi.chipset);
20	strcpy(adi->serial_no, "unknown");
21	adi->memory = si->ps.memory_size;
22	adi->dac_speed = si->ps.max_dac1_clock;
23
24	return B_OK;
25}
26
27#ifdef __HAIKU__
28
29/* Get the info fetched from the attached screen */
30status_t GET_EDID_INFO(void* info, size_t size, uint32* _version)
31{
32	if (!si->ps.crtc1_screen.have_full_edid && !si->ps.crtc2_screen.have_full_edid) {
33		LOG(4,("GET_EDID_INFO: EDID info not available\n"));
34		return B_ERROR;
35	}
36	if (size < sizeof(struct edid1_info)) {
37		LOG(4,("GET_EDID_INFO: not enough memory available\n"));
38		return B_BUFFER_OVERFLOW;
39	}
40
41	LOG(4,("GET_EDID_INFO: returning info\n"));
42
43	/* if we have two screens, make the best of it (go for the best compatible info) */
44	if (si->ps.crtc1_screen.have_full_edid && si->ps.crtc2_screen.have_full_edid) {
45		/* return info on screen with lowest aspect (4:3 takes precedence over ws)
46		 * NOTE:
47		 * allow 0.10 difference so 4:3 and 5:4 aspect screens are regarded as being the same. */
48		if (si->ps.crtc1_screen.aspect < (si->ps.crtc2_screen.aspect - 0.10)) {
49			memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
50		} else {
51			if (si->ps.crtc1_screen.aspect > (si->ps.crtc2_screen.aspect + 0.10)) {
52				memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
53			} else {
54				/* both screens have the same aspect, return info on the one with
55				 * the lowest native resolution */
56				if (si->ps.crtc1_screen.timing.h_display < si->ps.crtc2_screen.timing.h_display)
57					memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
58				if (si->ps.crtc1_screen.timing.h_display > si->ps.crtc2_screen.timing.h_display)
59					memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
60
61				/* if both screens have the same resolution and aspect, return info on the
62				 * one used as main screen */
63				if (si->ps.crtc1_screen.timing.h_display == si->ps.crtc2_screen.timing.h_display) {
64					if (si->ps.crtc2_prim)
65						memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
66					else
67						memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
68				}
69			}
70		}
71	} else {
72		/* there's just one screen of which we have EDID information, return it */
73		if (si->ps.crtc1_screen.have_full_edid)
74			memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
75		else
76			memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
77	}
78
79	*_version = EDID_VERSION_1;
80	return B_OK;
81}
82
83/* Return the optimum (native) mode for the attached screen */
84status_t GET_PREFERRED_DISPLAY_MODE(display_mode* preferredMode)
85{
86	if (si->ps.crtc1_screen.have_full_edid || si->ps.crtc2_screen.have_full_edid) {
87		LOG(4,("GET_PREFERRED_DISPLAY_MODE: full EDID known, aborting (fetch EDID instead).\n"));
88		return B_ERROR;
89	}
90
91	if (!si->ps.crtc1_screen.have_native_edid && !si->ps.crtc2_screen.have_native_edid) {
92		LOG(4,("GET_PREFERRED_DISPLAY_MODE: native mode(s) not known\n"));
93		return B_ERROR;
94	}
95
96	/* if we got here then we're probably on a laptop, but DDC/EDID may have failed
97	 * for another reason as well. */
98	LOG(4,("GET_PREFERRED_DISPLAY_MODE: returning mode\n"));
99
100	/* if we have two screens, make the best of it (go for the best compatible mode) */
101	if (si->ps.crtc1_screen.have_native_edid && si->ps.crtc2_screen.have_native_edid) {
102		/* return mode of screen with lowest aspect (4:3 takes precedence over ws)
103		 * NOTE:
104		 * allow 0.10 difference so 4:3 and 5:4 aspect screens are regarded as being the same. */
105		if (si->ps.crtc1_screen.aspect < (si->ps.crtc2_screen.aspect - 0.10)) {
106			get_crtc1_screen_native_mode(preferredMode);
107		} else {
108			if (si->ps.crtc1_screen.aspect > (si->ps.crtc2_screen.aspect + 0.10)) {
109				get_crtc2_screen_native_mode(preferredMode);
110			} else {
111				/* both screens have the same aspect, return mode of the one with
112				 * the lowest native resolution */
113				if (si->ps.crtc1_screen.timing.h_display < si->ps.crtc2_screen.timing.h_display)
114					get_crtc1_screen_native_mode(preferredMode);
115				if (si->ps.crtc1_screen.timing.h_display > si->ps.crtc2_screen.timing.h_display)
116					get_crtc2_screen_native_mode(preferredMode);
117
118				/* if both screens have the same resolution and aspect, return mode of the
119				 * one used as main screen */
120				if (si->ps.crtc1_screen.timing.h_display == si->ps.crtc2_screen.timing.h_display) {
121					if (si->ps.crtc2_prim)
122						get_crtc2_screen_native_mode(preferredMode);
123					else
124						get_crtc1_screen_native_mode(preferredMode);
125				}
126			}
127		}
128	} else {
129		/* there's just one screen of which we have native mode information, return it's mode */
130		if (si->ps.crtc1_screen.have_native_edid)
131			get_crtc1_screen_native_mode(preferredMode);
132		else
133			get_crtc2_screen_native_mode(preferredMode);
134	}
135
136	return B_OK;
137}
138
139#endif	// __HAIKU__
140