1 /* 2 Copyright (c) 2002, Thomas Kurschel 3 4 Part of Radeon driver 5 Multi-Monitor Settings interface 6 */ 7 8 9 #include "multimon.h" 10 #include "accelerant_ext.h" 11 12 #include <OS.h> 13 #include <Screen.h> 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 19 20 // prepare parameters so they recognized as tunneled settings 21 static void 22 PrepareTunnel(display_mode *mode, display_mode *low, display_mode *high) 23 { 24 memset(mode, 0, sizeof(*mode)); 25 26 // mark modes as settings tunnel 27 mode->space = low->space = high->space = 0; 28 low->virtual_width = 0xffff; 29 low->virtual_height = 0xffff; 30 high->virtual_width = 0; 31 high->virtual_height = 0; 32 mode->timing.pixel_clock = 0; 33 low->timing.pixel_clock = 'TKTK'; 34 high->timing.pixel_clock = 'KTKT'; 35 } 36 37 38 // retrieve value of setting "code" 39 static status_t 40 GetSetting(BScreen *screen, uint16 code, uint32 *setting) 41 { 42 display_mode mode, low, high; 43 status_t result; 44 45 result = TestMultiMonSupport(screen); 46 if (result != B_OK) 47 return result; 48 49 PrepareTunnel(&mode, &low, &high); 50 51 mode.h_display_start = code; 52 mode.v_display_start = 0; 53 54 result = screen->ProposeMode(&mode, &low, &high); 55 if (result != B_OK) 56 return result; 57 58 *setting = mode.timing.flags; 59 60 return B_OK; 61 } 62 63 64 // set setting "code" to "value" 65 static status_t 66 SetSetting(BScreen *screen, uint16 code, uint32 value) 67 { 68 display_mode mode, low, high; 69 status_t result; 70 71 result = TestMultiMonSupport(screen); 72 if (result != B_OK) 73 return result; 74 75 PrepareTunnel(&mode, &low, &high); 76 77 mode.h_display_start = code; 78 mode.v_display_start = 1; 79 mode.timing.flags = value; 80 81 return screen->ProposeMode(&mode, &low, &high); 82 } 83 84 85 // retrieve n-th supported value of setting "code" 86 static status_t 87 GetNthSupportedSetting(BScreen *screen, uint16 code, int32 idx, 88 uint32 *setting) 89 { 90 display_mode mode, low, high; 91 status_t result; 92 93 result = TestMultiMonSupport(screen); 94 if (result != B_OK) 95 return result; 96 97 PrepareTunnel(&mode, &low, &high); 98 99 mode.h_display_start = code; 100 mode.v_display_start = 2; 101 mode.timing.flags = idx; 102 103 result = screen->ProposeMode(&mode, &low, &high); 104 if (result != B_OK) 105 return result; 106 107 *setting = mode.timing.flags; 108 109 return B_OK; 110 } 111 112 113 // get current Swap Displays settings 114 status_t 115 GetSwapDisplays(BScreen *screen, bool *swap) 116 { 117 status_t result; 118 uint32 tmp; 119 120 result = GetSetting(screen, ms_swap, &tmp); 121 if (result != B_OK) 122 return result; 123 124 *swap = tmp != 0; 125 126 return B_OK; 127 } 128 129 130 // set "Swap Displays" 131 status_t 132 SetSwapDisplays(BScreen *screen, bool swap) 133 { 134 return SetSetting(screen, ms_swap, swap); 135 } 136 137 138 // get current "Use Laptop Panel" settings 139 status_t 140 GetUseLaptopPanel(BScreen *screen, bool *use) 141 { 142 status_t result; 143 uint32 tmp; 144 145 result = GetSetting(screen, ms_use_laptop_panel, &tmp); 146 if (result != B_OK) 147 return result; 148 149 *use = tmp != 0; 150 return B_OK; 151 } 152 153 154 // set "Use Laptop Panel" 155 status_t 156 SetUseLaptopPanel(BScreen *screen, bool use) 157 { 158 return SetSetting(screen, ms_use_laptop_panel, use); 159 } 160 161 162 // get n-th supported TV standard 163 status_t 164 GetNthSupportedTVStandard(BScreen *screen, int idx, uint32 *standard) 165 { 166 return GetNthSupportedSetting( 167 screen, ms_tv_standard, (int32)idx, standard); 168 } 169 170 171 // get current TV Standard settings 172 status_t 173 GetTVStandard(BScreen *screen, uint32 *standard) 174 { 175 return GetSetting(screen, ms_tv_standard, standard); 176 } 177 178 179 // set TV Standard 180 status_t 181 SetTVStandard(BScreen *screen, uint32 standard) 182 { 183 return SetSetting(screen, ms_tv_standard, standard); 184 } 185 186 187 // Verify existence of Multi-Monitor Settings Tunnel 188 status_t 189 TestMultiMonSupport(BScreen *screen) 190 { 191 display_mode *modeList = NULL; 192 display_mode low, high; 193 uint32 count; 194 status_t result; 195 196 // take any valid mode 197 result = screen->GetModeList(&modeList, &count); 198 if (result != B_OK) 199 return result; 200 201 if (count < 1) 202 return B_ERROR; 203 204 // set request bits 205 modeList[0].timing.flags |= RADEON_MODE_MULTIMON_REQUEST; 206 modeList[0].timing.flags &= ~RADEON_MODE_MULTIMON_REPLY; 207 low = high = modeList[0]; 208 209 result = screen->ProposeMode(&modeList[0], &low, &high); 210 if (result != B_OK) 211 goto out; 212 213 // check reply bits 214 if ((modeList[0].timing.flags & RADEON_MODE_MULTIMON_REQUEST) == 0 215 && (modeList[0].timing.flags & RADEON_MODE_MULTIMON_REPLY) != 0) 216 result = B_OK; 217 else 218 result = B_ERROR; 219 220 out: 221 free(modeList); 222 return result; 223 } 224