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 21static void 22PrepareTunnel(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" 39static status_t 40GetSetting(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" 65static status_t 66SetSetting(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" 86static status_t 87GetNthSupportedSetting(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 114status_t 115GetSwapDisplays(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" 131status_t 132SetSwapDisplays(BScreen *screen, bool swap) 133{ 134 return SetSetting(screen, ms_swap, swap); 135} 136 137 138// get current "Use Laptop Panel" settings 139status_t 140GetUseLaptopPanel(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" 155status_t 156SetUseLaptopPanel(BScreen *screen, bool use) 157{ 158 return SetSetting(screen, ms_use_laptop_panel, use); 159} 160 161 162// get n-th supported TV standard 163status_t 164GetNthSupportedTVStandard(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 172status_t 173GetTVStandard(BScreen *screen, uint32 *standard) 174{ 175 return GetSetting(screen, ms_tv_standard, standard); 176} 177 178 179// set TV Standard 180status_t 181SetTVStandard(BScreen *screen, uint32 standard) 182{ 183 return SetSetting(screen, ms_tv_standard, standard); 184} 185 186 187// Verify existence of Multi-Monitor Settings Tunnel 188status_t 189TestMultiMonSupport(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 220out: 221 free(modeList); 222 return result; 223} 224