vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / nvidia / GetDeviceInfo.c
blobabdc7e0158b0466ef46213d360754c83c957be97
1 /*
2 Author:
3 Rudolf Cornelissen 7/2004-08/2009
4 */
6 #define MODULE_BIT 0x04000000
8 #include "acc_std.h"
10 /* Get some info about the device */
11 status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info * adi)
13 LOG(4,("GET_ACCELERANT_DEVICE_INFO: returning info\n"));
15 /* no info on version is provided, so presumably this is for my info */
16 adi->version = 1;
18 sprintf(adi->name, si->adi.name);
19 sprintf(adi->chipset, si->adi.chipset);
20 sprintf(adi->serial_no, "unknown");
21 adi->memory = si->ps.memory_size;
22 adi->dac_speed = si->ps.max_dac1_clock;
24 return B_OK;
27 #ifdef __HAIKU__
29 /* Get the info fetched from the attached screen */
30 status_t GET_EDID_INFO(void* info, size_t size, uint32* _version)
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;
36 if (size < sizeof(struct edid1_info)) {
37 LOG(4,("GET_EDID_INFO: not enough memory available\n"));
38 return B_BUFFER_OVERFLOW;
41 LOG(4,("GET_EDID_INFO: returning info\n"));
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));
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));
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));
79 *_version = EDID_VERSION_1;
80 return B_OK;
83 /* Return the optimum (native) mode for the attached screen */
84 status_t GET_PREFERRED_DISPLAY_MODE(display_mode* preferredMode)
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;
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;
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"));
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);
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);
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);
136 return B_OK;
139 #endif // __HAIKU__