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 PrepareTunnel( 22 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 GetSetting( 40 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 SetSetting( 66 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 GetNthSupportedSetting( 87 BScreen *screen, uint16 code, int32 idx, uint32 *setting ) 88 { 89 display_mode mode, low, high; 90 status_t result; 91 92 result = TestMultiMonSupport( screen ); 93 if( result != B_OK ) 94 return result; 95 96 PrepareTunnel( &mode, &low, &high ); 97 98 mode.h_display_start = code; 99 mode.v_display_start = 2; 100 mode.timing.flags = idx; 101 102 result = screen->ProposeMode( &mode, &low, &high ); 103 if( result != B_OK ) 104 return result; 105 106 *setting = mode.timing.flags; 107 108 return B_OK; 109 } 110 111 112 // get current Swap Displays settings 113 status_t GetSwapDisplays( 114 BScreen *screen, bool *swap ) 115 { 116 status_t result; 117 uint32 tmp; 118 119 result = GetSetting( screen, ms_swap, &tmp ); 120 if( result != B_OK ) 121 return result; 122 123 *swap = tmp != 0; 124 125 return B_OK; 126 } 127 128 129 // set "Swap Displays" 130 status_t SetSwapDisplays( 131 BScreen *screen, bool swap ) 132 { 133 return SetSetting( screen, ms_swap, swap ); 134 } 135 136 137 // get current "Use Laptop Panel" settings 138 status_t GetUseLaptopPanel( 139 BScreen *screen, bool *use ) 140 { 141 status_t result; 142 uint32 tmp; 143 144 result = GetSetting( screen, ms_use_laptop_panel, &tmp ); 145 if( result != B_OK ) 146 return result; 147 148 *use = tmp != 0; 149 return B_OK; 150 } 151 152 153 // set "Use Laptop Panel" 154 status_t SetUseLaptopPanel( 155 BScreen *screen, bool use ) 156 { 157 return SetSetting( screen, ms_use_laptop_panel, use ); 158 } 159 160 161 // get n-th supported TV standard 162 status_t GetNthSupportedTVStandard( BScreen *screen, int idx, uint32 *standard ) 163 { 164 return GetNthSupportedSetting( 165 screen, ms_tv_standard, (int32)idx, standard ); 166 } 167 168 169 // get current TV Standard settings 170 status_t GetTVStandard( BScreen *screen, uint32 *standard ) 171 { 172 return GetSetting( screen, ms_tv_standard, standard ); 173 } 174 175 176 // set TV Standard 177 status_t SetTVStandard( BScreen *screen, uint32 standard ) 178 { 179 return SetSetting( screen, ms_tv_standard, standard ); 180 } 181 182 183 // Verify existence of Multi-Monitor Settings Tunnel 184 status_t 185 TestMultiMonSupport(BScreen *screen) 186 { 187 display_mode *modeList = NULL; 188 display_mode low, high; 189 uint32 count; 190 status_t result; 191 192 // take any valid mode 193 result = screen->GetModeList(&modeList, &count); 194 if (result != B_OK) 195 return result; 196 197 if (count < 1) 198 return B_ERROR; 199 200 // set request bits 201 modeList[0].timing.flags |= RADEON_MODE_MULTIMON_REQUEST; 202 modeList[0].timing.flags &= ~RADEON_MODE_MULTIMON_REPLY; 203 low = high = modeList[0]; 204 205 result = screen->ProposeMode(&modeList[0], &low, &high); 206 if (result != B_OK) 207 goto out; 208 209 // check reply bits 210 if ((modeList[0].timing.flags & RADEON_MODE_MULTIMON_REQUEST) == 0 211 && (modeList[0].timing.flags & RADEON_MODE_MULTIMON_REPLY) != 0) 212 result = B_OK; 213 else 214 result = B_ERROR; 215 216 out: 217 free(modeList); 218 return result; 219 } 220