00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <tqdir.h>
00026 #include <tqtimer.h>
00027 #include <tqstringlist.h>
00028 #include <tqregexp.h>
00029
00030 #include <tdelocale.h>
00031 #include <tdemessagebox.h>
00032 #include <tdeapplication.h>
00033
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036 #include <cmath>
00037
00038 #include "libtderandr.h"
00039
00040 #include <X11/extensions/dpms.h>
00041
00042
00043
00044 #define USE_XRANDR_PROGRAM
00045
00046
00047
00048 unsigned int reverse_bits(register unsigned int x)
00049 {
00050 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
00051 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
00052 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
00053 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
00054 return((x >> 16) | (x << 16));
00055 }
00056
00057
00058 TQString exec(const char * cmd) {
00059 TQString bashcommand = cmd;
00060 bashcommand = bashcommand.replace("\"", "\\\"");
00061 bashcommand = TQString("/bin/bash -c \"%1\" 2>&1").arg(bashcommand);
00062 FILE* pipe = popen(bashcommand.ascii(), "r");
00063 if (!pipe) return "ERROR";
00064 char buffer[128];
00065 TQString result = "";
00066 while(!feof(pipe)) {
00067 if(fgets(buffer, 128, pipe) != NULL) {
00068 result += buffer;
00069 }
00070 }
00071 pclose(pipe);
00072 result.remove(result.length(), 1);
00073 return result;
00074 }
00075
00076 TQString capitalizeString(TQString in) {
00077 return in.left(1).upper() + in.right(in.length()-1);
00078 }
00079
00080 TQString KRandrSimpleAPI::getIccFileName(TQString profileName, TQString screenName, TQString kde_confdir) {
00081 KSimpleConfig *t_config = NULL;
00082 KSimpleConfig *t_systemconfig = NULL;
00083 int t_numberOfProfiles;
00084 TQStringList t_cfgProfiles;
00085 TQString retval;
00086
00087 if ((profileName != NULL) && (profileName != "")) {
00088 t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
00089 t_config->setGroup(NULL);
00090 if (t_config->readBoolEntry("EnableICC", false) == true) {
00091 t_config->setGroup(profileName);
00092 retval = t_config->readEntry(screenName);
00093 }
00094 else {
00095 retval = "";
00096 }
00097 delete t_config;
00098 }
00099 else {
00100 t_systemconfig = new KSimpleConfig( kde_confdir + TQString("/kicc/kiccconfigrc") );
00101 t_systemconfig->setGroup(NULL);
00102 if (t_systemconfig->readBoolEntry("EnableICC", false) == true) {
00103 retval = t_systemconfig->readEntry("ICCFile");
00104 }
00105 else {
00106 retval = "";
00107 }
00108 delete t_systemconfig;
00109 }
00110
00111 return retval;
00112 }
00113
00114 TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
00115 int i;
00116 int j;
00117 Display *randr_display;
00118 ScreenInfo *randr_screen_info;
00119 XRROutputInfo *output_info;
00120
00121 int screenNumber = 0;
00122
00123 if (fileName != "") {
00124
00125
00126
00127
00128
00129
00130
00131
00132 if (isValid() == true) {
00133 screenNumber = -1;
00134 randr_display = tqt_xdisplay();
00135 randr_screen_info = read_screen_info(randr_display);
00136 if (randr_screen_info == NULL) {
00137 return "";
00138 }
00139 j=0;
00140 for (i = 0; i < randr_screen_info->n_output; i++) {
00141 output_info = randr_screen_info->outputs[i]->info;
00142
00143 if (!randr_screen_info->outputs[i]->cur_crtc) {
00144 continue;
00145 }
00146
00147 if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
00148 continue;
00149 }
00150 if (output_info->name == screenName) {
00151 screenNumber = j;
00152 }
00153 j++;
00154 }
00155 freeScreenInfoStructure(randr_screen_info);
00156 }
00157
00158 if (screenNumber >= 0) {
00159
00160 TQString icc_command;
00161 FILE *pipe_xcalib;
00162 char xcalib_result[2048];
00163 int i;
00164 xcalib_result[0]=0;
00165
00166 icc_command = TQString("xcalib \"%1\"").arg(fileName);
00167 if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
00168 {
00169 printf("Xcalib pipe error\n [xcalib apply]");
00170 }
00171 else {
00172 if (fgets(xcalib_result, 2048, pipe_xcalib)) {
00173 pclose(pipe_xcalib);
00174 for (i=1;i<2048;i++) {
00175 if (xcalib_result[i] == 0) {
00176 xcalib_result[i-1]=0;
00177 i=2048;
00178 }
00179 }
00180 if (strlen(xcalib_result) > 2) {
00181 return xcalib_result;
00182 }
00183 }
00184 else {
00185 return "";
00186 }
00187 }
00188 }
00189 }
00190 else {
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 if (isValid() == true) {
00202 screenNumber = -1;
00203 randr_display = tqt_xdisplay();
00204 randr_screen_info = read_screen_info(randr_display);
00205 if (randr_screen_info == NULL) {
00206 return "";
00207 }
00208 j=0;
00209 for (i = 0; i < randr_screen_info->n_output; i++) {
00210 output_info = randr_screen_info->outputs[i]->info;
00211
00212 if (!randr_screen_info->outputs[i]->cur_crtc) {
00213 continue;
00214 }
00215
00216 if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
00217 continue;
00218 }
00219 if (output_info->name == screenName) {
00220 screenNumber = j;
00221 }
00222 j++;
00223 }
00224 freeScreenInfoStructure(randr_screen_info);
00225 }
00226
00227 if (screenNumber >= 0) {
00228
00229 TQString icc_command;
00230 FILE *pipe_xcalib;
00231 char xcalib_result[2048];
00232 int i;
00233 xcalib_result[0]=0;
00234
00235 icc_command = TQString("xcalib -c");
00236 if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
00237 {
00238 printf("Xcalib pipe error\n [xcalib clear]");
00239 }
00240 else {
00241 if (fgets(xcalib_result, 2048, pipe_xcalib)) {
00242 pclose(pipe_xcalib);
00243 for (i=1;i<2048;i++) {
00244 if (xcalib_result[i] == 0) {
00245 xcalib_result[i-1]=0;
00246 i=2048;
00247 }
00248 }
00249 if (strlen(xcalib_result) > 2) {
00250 return xcalib_result;
00251 }
00252 }
00253 else {
00254 return "";
00255 }
00256 }
00257 }
00258 }
00259 return "";
00260 }
00261
00262 TQString KRandrSimpleAPI::applyIccConfiguration(TQString profileName, TQString kde_confdir) {
00263 int i;
00264 Display *randr_display;
00265 ScreenInfo *randr_screen_info;
00266 XRROutputInfo *output_info;
00267 KSimpleConfig *t_config;
00268
00269 int screenNumber = 0;
00270 TQString errorstr = "";
00271
00272 t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
00273
00274
00275 if (isValid() == true) {
00276 randr_display = tqt_xdisplay();
00277 randr_screen_info = read_screen_info(randr_display);
00278 if (randr_screen_info == NULL) {
00279 return "";
00280 }
00281 for (i = 0; i < randr_screen_info->n_output; i++) {
00282 output_info = randr_screen_info->outputs[i]->info;
00283 errorstr = applyIccFile(output_info->name, getIccFileName(profileName, output_info->name, kde_confdir));
00284 if (errorstr != "") {
00285 return errorstr;
00286 }
00287 }
00288 freeScreenInfoStructure(randr_screen_info);
00289 }
00290 else {
00291 return applyIccFile(getIccFileName(profileName, "Default", kde_confdir), "Default");
00292 }
00293
00294 t_config->writeEntry("CurrentProfile", profileName);
00295 t_config->sync();
00296 delete t_config;
00297
00298 return "";
00299 }
00300
00301 TQString KRandrSimpleAPI::getEDIDMonitorName(int card, TQString displayname) {
00302 TQString edid;
00303 TQByteArray binaryedid = getEDID(card, displayname);
00304 if (binaryedid.isNull())
00305 return TQString();
00306
00307
00308 unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
00309 unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
00310 unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
00311 TQChar qletter_1 = TQChar(letter_1);
00312 TQChar qletter_2 = TQChar(letter_2);
00313 TQChar qletter_3 = TQChar(letter_3);
00314 TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
00315
00316
00317 unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
00318
00319 unsigned int model_id = reverse_bits(raw_model_id);
00320
00321
00322 bool has_friendly_name = false;
00323 unsigned char descriptor_block[18];
00324 int i;
00325 for (i=72;i<90;i++) {
00326 descriptor_block[i-72] = binaryedid[i] & 0xFF;
00327 }
00328 if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
00329 for (i=90;i<108;i++) {
00330 descriptor_block[i-90] = binaryedid[i] & 0xFF;
00331 }
00332 if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
00333 for (i=108;i<126;i++) {
00334 descriptor_block[i-108] = binaryedid[i] & 0xFF;
00335 }
00336 }
00337 }
00338
00339 TQString monitor_name;
00340 if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
00341 char* pos = strchr((char *)(descriptor_block+5), '\n');
00342 if (pos) {
00343 *pos = 0;
00344 has_friendly_name = true;
00345 monitor_name = TQString((char *)(descriptor_block+5));
00346 }
00347 else {
00348 has_friendly_name = false;
00349 }
00350 }
00351
00352
00353
00354
00355 if (has_friendly_name)
00356 edid = TQString("%1 %2").arg(manufacturer_id).arg(monitor_name);
00357 else
00358 edid = TQString("%1 0x%2").arg(manufacturer_id).arg(model_id, 0, 16);
00359
00360 return edid;
00361 }
00362
00363 TQByteArray KRandrSimpleAPI::getEDID(int card, TQString displayname) {
00364 TQFile file(TQString("/sys/class/drm/card%1-%2/edid").arg(card).arg(displayname));
00365 if (!file.open (IO_ReadOnly))
00366 return TQByteArray();
00367 TQByteArray binaryedid = file.readAll();
00368 file.close();
00369 return binaryedid;
00370 }
00371
00372 TQString KRandrSimpleAPI::getCurrentProfile () {
00373 TQString profileName;
00374 KSimpleConfig *t_config;
00375
00376 t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
00377 profileName = t_config->readEntry("CurrentProfile");
00378 delete t_config;
00379 return profileName;
00380 }
00381
00382 TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir) {
00383
00384 TQString icc_command;
00385 FILE *pipe_xcalib;
00386 char xcalib_result[2048];
00387 int i;
00388 xcalib_result[0]=0;
00389
00390 icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir));
00391 if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
00392 {
00393 printf("Xcalib pipe error [xcalib apply]\n");
00394 }
00395 else {
00396 if (fgets(xcalib_result, 2048, pipe_xcalib)) {
00397 pclose(pipe_xcalib);
00398 for (i=1;i<2048;i++) {
00399 if (xcalib_result[i] == 0) {
00400 xcalib_result[i-1]=0;
00401 i=2048;
00402 }
00403 }
00404 if (strlen(xcalib_result) > 2) {
00405 return xcalib_result;
00406 }
00407 }
00408 else {
00409 return "";
00410 }
00411 }
00412 return "";
00413 }
00414
00415 TQStringList KRandrSimpleAPI::getDisplayConfigurationProfiles(TQString kde_confdir) {
00416 TQStringList ret;
00417
00418 TQDir d(kde_confdir + "/displayconfig/");
00419 d.setFilter(TQDir::Files);
00420 d.setSorting(TQDir::Name);
00421
00422 const TQFileInfoList *list = d.entryInfoList();
00423 if (list) {
00424 TQFileInfoListIterator it(*list);
00425 TQFileInfo *fi;
00426
00427 while ((fi = it.current()) != 0) {
00428 if (fi->fileName() != "default") {
00429 ret.append(fi->fileName());
00430 }
00431 ++it;
00432 }
00433 }
00434
00435 return ret;
00436 }
00437
00438 bool KRandrSimpleAPI::deleteDisplayConfiguration(TQString profilename, TQString kde_confdir) {
00439 TQString fileName = kde_confdir + "/displayconfig/";
00440 fileName.append(profilename);
00441 return (!unlink(fileName.ascii()));
00442 }
00443
00444 bool KRandrSimpleAPI::renameDisplayConfiguration(TQString profilename, TQString newprofilename, TQString kde_confdir) {
00445 TQString fileName = kde_confdir + "/displayconfig/";
00446 TQString newFileName = fileName;
00447 fileName.append(profilename);
00448 newFileName.append(newprofilename);
00449 TQDir d(kde_confdir + "/displayconfig/");
00450 return (d.rename(fileName, newFileName));
00451 }
00452
00453 void KRandrSimpleAPI::saveDisplayConfiguration(bool enable, bool applyonstart, TQString profilename, TQString defaultprofilename, TQString kde_confdir, TQPtrList<SingleScreenData> screenInfoArray) {
00454 int i;
00455
00456 TQString filename;
00457
00458 filename = "displayglobals";
00459 filename.prepend(kde_confdir.append("/"));
00460 KSimpleConfig* display_config = new KSimpleConfig( filename );
00461 display_config->setGroup("General");
00462 display_config->writeEntry("EnableDisplayControl", enable);
00463 display_config->writeEntry("ApplySettingsOnStart", applyonstart);
00464 display_config->writeEntry("StartupProfileName", defaultprofilename);
00465 display_config->sync();
00466 delete display_config;
00467
00468 filename = profilename;
00469 if (filename == "") {
00470 filename = "default";
00471 }
00472 filename.prepend(kde_confdir.append("/displayconfig/"));
00473
00474 display_config = new KSimpleConfig( filename );
00475
00476 i=0;
00477 SingleScreenData *screendata;
00478 for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
00479 display_config->setGroup(TQString("SCREEN %1").arg(i));
00480 display_config->writeEntry("ScreenUniqueName", screendata->screenUniqueName);
00481 display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName);
00482 display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected);
00483 display_config->writeEntry("ScreenConnected", screendata->screen_connected);
00484 display_config->writeEntry("Resolutions", screendata->resolutions);
00485 display_config->writeEntry("RefreshRates", screendata->refresh_rates);
00486 display_config->writeEntry("ColorDepths", screendata->color_depths);
00487 display_config->writeEntry("AvailableRotations", screendata->rotations);
00488 display_config->writeEntry("CurrentResolution", screendata->current_resolution_index);
00489 display_config->writeEntry("CurrentRefreshRate", screendata->current_refresh_rate_index);
00490 display_config->writeEntry("CurrentColorDepth", screendata->current_color_depth_index);
00491 display_config->writeEntry("CurrentRotation", screendata->current_rotation_index);
00492 display_config->writeEntry("CurrentOrientiation", screendata->current_orientation_mask);
00493 display_config->writeEntry("GammaRed", screendata->gamma_red);
00494 display_config->writeEntry("GammaGreen", screendata->gamma_green);
00495 display_config->writeEntry("GammaBlue", screendata->gamma_blue);
00496 display_config->writeEntry("CurrentXFlip", screendata->has_x_flip);
00497 display_config->writeEntry("CurrentYFlip", screendata->has_y_flip);
00498 display_config->writeEntry("SupportsTransformation", screendata->supports_transformations);
00499 display_config->writeEntry("IsPrimary", screendata->is_primary);
00500 display_config->writeEntry("IsExtended", screendata->is_extended);
00501 display_config->writeEntry("AbsXPos", screendata->absolute_x_position);
00502 display_config->writeEntry("AbsYPos", screendata->absolute_y_position);
00503 display_config->writeEntry("CurrentXPixelCount", screendata->current_x_pixel_count);
00504 display_config->writeEntry("CurrentYPixelCount", screendata->current_y_pixel_count);
00505 display_config->writeEntry("HasDPMS", screendata->has_dpms);
00506 display_config->writeEntry("EnableDPMS", screendata->enable_dpms);
00507 display_config->writeEntry("DPMSStandbyDelay", screendata->dpms_standby_delay);
00508 display_config->writeEntry("DPMSSuspendDelay", screendata->dpms_suspend_delay);
00509 display_config->writeEntry("DPMSPowerDownDelay", screendata->dpms_off_delay);
00510 i++;
00511 }
00512
00513 display_config->sync();
00514 delete display_config;
00515 }
00516
00517 TQPoint KRandrSimpleAPI::applyStartupDisplayConfiguration(TQString kde_confdir) {
00518 bool applyonstart = getDisplayConfigurationStartupAutoApplyEnabled(kde_confdir);
00519 if (applyonstart) {
00520 TQString profilename = getDisplayConfigurationStartupAutoApplyName(kde_confdir);
00521 return applyDisplayConfiguration(profilename, kde_confdir);
00522 }
00523 else {
00524 return TQPoint();
00525 }
00526 }
00527
00528 TQPoint KRandrSimpleAPI::applyDisplayConfiguration(TQString profilename, TQString kde_confdir) {
00529 TQPoint ret;
00530
00531 bool enabled = getDisplayConfigurationEnabled(kde_confdir);
00532 if (profilename == "") {
00533 profilename = "default";
00534 }
00535
00536 if (enabled) {
00537 TQPtrList<SingleScreenData> screenInfoArray;
00538 screenInfoArray = loadDisplayConfiguration(profilename, kde_confdir);
00539 if (screenInfoArray.count() > 0) {
00540 applyDisplayConfiguration(screenInfoArray, FALSE, kde_confdir);
00541 }
00542 destroyScreenInformationObject(screenInfoArray);
00543 screenInfoArray = readCurrentDisplayConfiguration();
00544 ensureMonitorDataConsistency(screenInfoArray);
00545 ret = primaryScreenOffsetFromTLC(screenInfoArray);
00546 destroyScreenInformationObject(screenInfoArray);
00547 }
00548
00549 return ret;
00550 }
00551
00552 TQPtrList<SingleScreenData> KRandrSimpleAPI::loadDisplayConfiguration(TQString profilename, TQString kde_confdir) {
00553 int i;
00554
00555 TQString filename;
00556 filename = profilename;
00557 if (filename == "") {
00558 filename = "default";
00559 }
00560 filename.prepend(kde_confdir.append("/displayconfig/"));
00561
00562 KSimpleConfig* display_config = new KSimpleConfig( filename );
00563
00564 TQStringList grouplist = display_config->groupList();
00565 SingleScreenData *screendata;
00566 TQPtrList<SingleScreenData> screenInfoArray;
00567 for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) {
00568 if ((*it).startsWith("SCREEN ")) {
00569 display_config->setGroup(*it);
00570 i = ((*it).remove("SCREEN ")).toInt();
00571 screendata = new SingleScreenData;
00572 screenInfoArray.append(screendata);
00573 screendata->screenUniqueName = display_config->readEntry("ScreenUniqueName");
00574 screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName");
00575 screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected");
00576 screendata->screen_connected = display_config->readBoolEntry("ScreenConnected");
00577 screendata->resolutions = display_config->readListEntry("Resolutions");
00578 screendata->refresh_rates = display_config->readListEntry("RefreshRates");
00579 screendata->color_depths = display_config->readListEntry("ColorDepths");
00580 screendata->rotations = display_config->readListEntry("AvailableRotations");
00581 screendata->current_resolution_index = display_config->readNumEntry("CurrentResolution");
00582 screendata->current_refresh_rate_index = display_config->readNumEntry("CurrentRefreshRate");
00583 screendata->current_color_depth_index = display_config->readNumEntry("CurrentColorDepth");
00584 screendata->current_rotation_index = display_config->readNumEntry("CurrentRotation");
00585 screendata->current_orientation_mask = display_config->readNumEntry("CurrentOrientiation");
00586 screendata->gamma_red = display_config->readDoubleNumEntry("GammaRed");
00587 screendata->gamma_green = display_config->readDoubleNumEntry("GammaGreen");
00588 screendata->gamma_blue = display_config->readDoubleNumEntry("GammaBlue");
00589 screendata->has_x_flip = display_config->readBoolEntry("CurrentXFlip");
00590 screendata->has_y_flip = display_config->readBoolEntry("CurrentYFlip");
00591 screendata->supports_transformations = display_config->readBoolEntry("SupportsTransformation");
00592 screendata->is_primary = display_config->readBoolEntry("IsPrimary");
00593 screendata->is_extended = display_config->readBoolEntry("IsExtended");
00594 screendata->absolute_x_position = display_config->readNumEntry("AbsXPos");
00595 screendata->absolute_y_position = display_config->readNumEntry("AbsYPos");
00596 screendata->current_x_pixel_count = display_config->readNumEntry("CurrentXPixelCount");
00597 screendata->current_y_pixel_count = display_config->readNumEntry("CurrentYPixelCount");
00598 screendata->has_dpms = display_config->readBoolEntry("HasDPMS");
00599 screendata->enable_dpms = display_config->readBoolEntry("EnableDPMS");
00600 screendata->dpms_standby_delay = display_config->readNumEntry("DPMSStandbyDelay");
00601 screendata->dpms_suspend_delay = display_config->readNumEntry("DPMSSuspendDelay");
00602 screendata->dpms_off_delay = display_config->readNumEntry("DPMSPowerDownDelay");
00603 }
00604 }
00605
00606 delete display_config;
00607
00608 return screenInfoArray;
00609 }
00610
00611 int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
00612 int rotationFlags = 0;
00613 TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
00614 if (rotationDesired == ROTATION_0_DEGREES_STRING) {
00615 rotationFlags = rotationFlags | RandRScreen::Rotate0;
00616 }
00617 else if (rotationDesired == ROTATION_90_DEGREES_STRING) {
00618 rotationFlags = rotationFlags | RandRScreen::Rotate90;
00619 }
00620 else if (rotationDesired == ROTATION_180_DEGREES_STRING) {
00621 rotationFlags = rotationFlags | RandRScreen::Rotate180;
00622 }
00623 else if (rotationDesired == ROTATION_270_DEGREES_STRING) {
00624 rotationFlags = rotationFlags | RandRScreen::Rotate270;
00625 }
00626 if (screendata->has_x_flip) {
00627 rotationFlags = rotationFlags | RandRScreen::ReflectX;
00628 }
00629 if (screendata->has_y_flip) {
00630 rotationFlags = rotationFlags | RandRScreen::ReflectY;
00631 }
00632 return rotationFlags;
00633 }
00634
00635 #define USE_XRANDR_PROGRAM
00636
00637 bool KRandrSimpleAPI::applyDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test, TQString kde_confdir) {
00638 int i;
00639 int j;
00640 bool accepted = true;
00641 Display *randr_display;
00642 XRROutputInfo *output_info;
00643 ScreenInfo *randr_screen_info;
00644
00645 SingleScreenData *screendata;
00646
00647 TQPtrList<SingleScreenData> oldconfig;
00648 if (test == TRUE) {
00649 oldconfig = readCurrentDisplayConfiguration();
00650 }
00651
00652 if (isValid() == true) {
00653 #ifdef USE_XRANDR_PROGRAM
00654
00655 TQString command;
00656 command = "xrandr";
00657
00658 randr_display = tqt_xdisplay();
00659 randr_screen_info = read_screen_info(randr_display);
00660 for (i = 0; i < screenInfoArray.count(); i++) {
00661 screendata = screenInfoArray.at(i);
00662 if (screendata) {
00663 output_info = randr_screen_info->outputs[i]->info;
00664 command.append(" --output ").append(output_info->name);
00665 if (screendata->is_primary || screendata->is_extended) {
00666 command.append(TQString(" --mode %1x%2").arg(screendata->current_x_pixel_count).arg(screendata->current_y_pixel_count));
00667 command.append(TQString(" --pos %1x%2").arg(screendata->absolute_x_position).arg(screendata->absolute_y_position));
00668 command.append(TQString(" --refresh %1").arg(atoi((*screendata->refresh_rates.at(screendata->current_refresh_rate_index)).ascii())));
00669 command.append(TQString(" --gamma %1:%2:%3").arg(screendata->gamma_red).arg(screendata->gamma_green).arg(screendata->gamma_blue));
00670 if (screendata->current_rotation_index == 0) command.append(" --rotate ").append("normal");
00671 if (screendata->current_rotation_index == 1) command.append(" --rotate ").append("left");
00672 if (screendata->current_rotation_index == 2) command.append(" --rotate ").append("inverted");
00673 if (screendata->current_rotation_index == 3) command.append(" --rotate ").append("right");
00674 if ((screendata->has_x_flip == 0) && (screendata->has_y_flip == 0)) command.append(" --reflect ").append("normal");
00675 if ((screendata->has_x_flip == 1) && (screendata->has_y_flip == 0)) command.append(" --reflect ").append("x");
00676 if ((screendata->has_x_flip == 0) && (screendata->has_y_flip == 1)) command.append(" --reflect ").append("y");
00677 if ((screendata->has_x_flip == 1) && (screendata->has_y_flip == 1)) command.append(" --reflect ").append("xy");
00678 if (screendata->is_primary) {
00679 command.append(" --primary");
00680 }
00681 }
00682 else {
00683 command.append(" --off");
00684 }
00685 }
00686 else {
00687 printf("[WARNING] Unable to find configuration for monitor %d; settings may not be correctly applied...\n", i); fflush(stdout);
00688 }
00689 }
00690 freeScreenInfoStructure(randr_screen_info);
00691
00692 TQString xrandr_command_output = exec(command.ascii());
00693 xrandr_command_output = xrandr_command_output.stripWhiteSpace();
00694 if (test) {
00695
00696 if (xrandr_command_output == "xrandr: Gamma size is 0.") {
00697 command = command.replace(TQRegExp("--gamma [0-9\\.]*:[0-9\\.]*:[0-9\\.]*"), "");
00698 xrandr_command_output = exec(command.ascii());
00699 xrandr_command_output = xrandr_command_output.stripWhiteSpace();
00700 }
00701
00702 if(xrandr_command_output.startsWith("xrandr: Failed to get size of gamma for output")) {
00703 KMessageBox::sorry(0, xrandr_command_output, i18n("Setting gamma failed."));
00704 } else if (xrandr_command_output != "") {
00705 applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
00706 accepted = false;
00707 destroyScreenInformationObject(oldconfig);
00708 KMessageBox::sorry(0, xrandr_command_output, i18n("XRandR encountered a problem"));
00709 return accepted;
00710 }
00711 }
00712 #else
00713 randr_display = tqt_xdisplay();
00714 randr_screen_info = read_screen_info(randr_display);
00715
00716 for (i = 0; i < screenInfoArray.count(); i++) {
00717 screendata = screenInfoArray.at(i);
00718 output_info = randr_screen_info->outputs[i]->info;
00719
00720 randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
00721 randr_screen_info->cur_output = randr_screen_info->outputs[i];
00722 randr_screen_info->cur_output->auto_set = 0;
00723 randr_screen_info->cur_output->off_set = 1;
00724 output_off (randr_screen_info, randr_screen_info->cur_output);
00725 j=main_low_apply(randr_screen_info);
00726 }
00727 freeScreenInfoStructure(randr_screen_info);
00728 randr_screen_info = read_screen_info(randr_display);
00729
00730 for (i = 0; i < screenInfoArray.count(); i++) {
00731 screendata = screenInfoArray.at(i);
00732 output_info = randr_screen_info->outputs[i]->info;
00733
00734 if (screendata->is_primary == true) {
00735 randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
00736 randr_screen_info->cur_output = randr_screen_info->outputs[i];
00737 randr_screen_info->cur_output->auto_set = 1;
00738 randr_screen_info->cur_output->off_set = 0;
00739 output_auto (randr_screen_info, randr_screen_info->cur_output);
00740 j=main_low_apply(randr_screen_info);
00741 }
00742 }
00743 freeScreenInfoStructure(randr_screen_info);
00744
00745 randr_screen_info = read_screen_info(randr_display);
00746 for (i = 0; i < screenInfoArray.count(); i++) {
00747 screendata = screenInfoArray.at(i);
00748 output_info = randr_screen_info->outputs[i]->info;
00749
00750
00751 randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
00752 randr_screen_info->cur_output = randr_screen_info->outputs[i];
00753 if (screendata->is_primary == false) {
00754 if (screendata->is_primary || screendata->is_extended) {
00755 randr_screen_info->cur_output->auto_set = 1;
00756 randr_screen_info->cur_output->off_set = 0;
00757 output_auto (randr_screen_info, randr_screen_info->cur_output);
00758 j=main_low_apply(randr_screen_info);
00759 }
00760 else {
00761 randr_screen_info->cur_output->auto_set = 0;
00762 randr_screen_info->cur_output->off_set = 1;
00763 output_off (randr_screen_info, randr_screen_info->cur_output);
00764 j=main_low_apply(randr_screen_info);
00765 }
00766 }
00767 }
00768 freeScreenInfoStructure(randr_screen_info);
00769 randr_screen_info = read_screen_info(randr_display);
00770 for (i = 0; i < screenInfoArray.count(); i++) {
00771 screendata = screenInfoArray.at(i);
00772 output_info = randr_screen_info->outputs[i]->info;
00773
00774 if (screendata->is_primary || screendata->is_extended) {
00775
00776 RandRScreen *cur_screen = new RandRScreen(i);
00777 cur_screen->proposeSize(screendata->current_resolution_index);
00778 cur_screen->proposeRefreshRate(screendata->current_refresh_rate_index);
00779 cur_screen->proposeRotation(getHardwareRotationFlags(screendata));
00780 cur_screen->applyProposed();
00781 delete cur_screen;
00782
00783
00784 randr_screen_info = read_screen_info(randr_display);
00785 output_info = randr_screen_info->outputs[i]->info;
00786
00787
00788 randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
00789 if (randr_screen_info->cur_crtc) {
00790 randr_screen_info->cur_crtc->cur_x = screendata->absolute_x_position;
00791 randr_screen_info->cur_crtc->cur_y = screendata->absolute_y_position;
00792 j=main_low_apply(randr_screen_info);
00793 }
00794 }
00795 }
00796 freeScreenInfoStructure(randr_screen_info);
00797 #endif
00798 }
00799
00800 applyDisplayGamma(screenInfoArray);
00801 applyDisplayDPMS(screenInfoArray);
00802 TQString current_icc_profile = getCurrentProfile();
00803 applySystemWideIccConfiguration(kde_confdir);
00804 applyIccConfiguration(current_icc_profile, kde_confdir);
00805
00806 if (test == TRUE) {
00807 int ret = showTestConfigurationDialog();
00808 if (!ret) {
00809 applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
00810 accepted = false;
00811 }
00812 destroyScreenInformationObject(oldconfig);
00813 }
00814
00815 return accepted;
00816 }
00817
00818 TQPtrList<SingleScreenData> KRandrSimpleAPI::copyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
00819 SingleScreenData *origscreendata;
00820 SingleScreenData *copyscreendata;
00821 TQPtrList<SingleScreenData> retArray;
00822 for ( origscreendata = screenInfoArray.first(); origscreendata; origscreendata = screenInfoArray.next() ) {
00823 copyscreendata = new SingleScreenData;
00824 *copyscreendata = *origscreendata;
00825 retArray.append(copyscreendata);
00826 }
00827 return retArray;
00828 }
00829
00830 void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
00831 SingleScreenData *screendata;
00832 for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) {
00833 screenInfoArray.remove(screendata);
00834 delete screendata;
00835 }
00836 }
00837
00838 void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> screenInfoArray) {
00839 int i;
00840 SingleScreenData *screendata;
00841
00842 int numberOfScreens = screenInfoArray.count();
00843
00844 for (i=0;i<numberOfScreens;i++) {
00845 screendata = screenInfoArray.at(i);
00846 if (!screendata->screen_connected) {
00847 screendata->is_primary = false;
00848 screendata->is_extended = false;
00849 }
00850 }
00851
00852 bool has_primary_monitor = false;
00853 for (i=0;i<numberOfScreens;i++) {
00854 screendata = screenInfoArray.at(i);
00855 if (screendata->is_primary) {
00856 has_primary_monitor = true;
00857 }
00858 }
00859 if (!has_primary_monitor) {
00860 for (i=0;i<numberOfScreens;i++) {
00861 screendata = screenInfoArray.at(i);
00862 if (!has_primary_monitor) {
00863 if (screendata->screen_connected && screendata->is_extended) {
00864 screendata->is_primary = true;
00865 screendata->is_extended = true;
00866 has_primary_monitor = true;
00867 }
00868 }
00869 }
00870 }
00871 if (!has_primary_monitor) {
00872 for (i=0;i<numberOfScreens;i++) {
00873 screendata = screenInfoArray.at(i);
00874 if (!has_primary_monitor) {
00875 if (screendata->screen_connected) {
00876 screendata->is_primary = true;
00877 screendata->is_extended = true;
00878 has_primary_monitor = true;
00879 }
00880 }
00881 }
00882 }
00883
00884 bool found_first_primary_monitor = false;
00885 for (i=0;i<numberOfScreens;i++) {
00886 screendata = screenInfoArray.at(i);
00887 if (screendata->is_primary) {
00888 if (!found_first_primary_monitor) {
00889 found_first_primary_monitor = true;
00890 }
00891 else {
00892 screendata->is_primary = false;
00893 }
00894 }
00895 }
00896
00897 for (i=0;i<numberOfScreens;i++) {
00898 screendata = screenInfoArray.at(i);
00899 if (screendata->is_primary) {
00900 screendata->is_extended = true;
00901 }
00902 }
00903
00904 for (i=0;i<numberOfScreens;i++) {
00905 screendata = screenInfoArray.at(i);
00906 TQString resolutionstring = screendata->resolutions[screendata->current_resolution_index];
00907 int separator_pos = resolutionstring.find(" x ");
00908 TQString x_res_string = resolutionstring.left(separator_pos);
00909 TQString y_res_string = resolutionstring.right(resolutionstring.length()-separator_pos-3);
00910 screendata->current_x_pixel_count = x_res_string.toInt();
00911 screendata->current_y_pixel_count = y_res_string.toInt();
00912 screendata->current_orientation_mask = getHardwareRotationFlags(screendata);
00913 }
00914
00915
00916
00917 int primary_offset_x = 0;
00918 int primary_offset_y = 0;
00919 for (i=0;i<numberOfScreens;i++) {
00920 screendata = screenInfoArray.at(i);
00921 if (screendata->is_primary) {
00922 primary_offset_x = screendata->absolute_x_position;
00923 primary_offset_y = screendata->absolute_y_position;
00924 primary_offset_x = primary_offset_x * (-1);
00925 primary_offset_y = primary_offset_y * (-1);
00926 }
00927 }
00928 for (i=0;i<numberOfScreens;i++) {
00929 screendata = screenInfoArray.at(i);
00930 screendata->absolute_x_position = screendata->absolute_x_position + primary_offset_x;
00931 screendata->absolute_y_position = screendata->absolute_y_position + primary_offset_y;
00932 }
00933 }
00934
00935 TQPoint KRandrSimpleAPI::primaryScreenOffsetFromTLC(TQPtrList<SingleScreenData> screenInfoArray) {
00936 int i;
00937 SingleScreenData *screendata;
00938 int numberOfScreens = screenInfoArray.count();
00939
00940 int primary_offset_x = 0;
00941 int primary_offset_y = 0;
00942 for (i=0;i<numberOfScreens;i++) {
00943 screendata = screenInfoArray.at(i);
00944 if (screendata->absolute_x_position < primary_offset_x) {
00945 primary_offset_x = screendata->absolute_x_position;
00946 }
00947 if (screendata->absolute_y_position < primary_offset_y) {
00948 primary_offset_y = screendata->absolute_y_position;
00949 }
00950 }
00951 primary_offset_x = primary_offset_x * (-1);
00952 primary_offset_y = primary_offset_y * (-1);
00953
00954 return TQPoint(primary_offset_x, primary_offset_y);
00955 }
00956
00957 HotPlugRulesList KRandrSimpleAPI::getHotplugRules(TQString kde_confdir) {
00958 int i;
00959 TQString filename;
00960 HotPlugRulesList ret;
00961
00962 filename = "displayglobals";
00963 filename.prepend(kde_confdir.append("/"));
00964 KSimpleConfig* display_config = new KSimpleConfig( filename );
00965
00966 TQStringList grouplist = display_config->groupList();
00967 for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) {
00968 if (!(*it).startsWith("Hotplug-Rule")) {
00969 continue;
00970 }
00971 HotPlugRule rule;
00972 display_config->setGroup(*it);
00973 rule.outputs = display_config->readListEntry("Outputs");
00974 rule.states = display_config->readIntListEntry("States");
00975 rule.profileName = display_config->readEntry("Profile");
00976 ret.append(rule);
00977 }
00978 delete display_config;
00979
00980 return ret;
00981 }
00982
00983 void KRandrSimpleAPI::saveHotplugRules(HotPlugRulesList rules, TQString kde_confdir) {
00984 int i;
00985 TQString filename;
00986
00987 filename = "displayglobals";
00988 filename.prepend(kde_confdir.append("/"));
00989 KSimpleConfig* display_config = new KSimpleConfig( filename );
00990 TQStringList grouplist = display_config->groupList();
00991 for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) {
00992 if (!(*it).startsWith("Hotplug-Rule")) {
00993 continue;
00994 }
00995 display_config->deleteGroup(*it, true, false);
00996 }
00997 HotPlugRulesList::Iterator it;
00998 i=0;
00999 for (it=rules.begin(); it != rules.end(); ++it) {
01000 display_config->setGroup(TQString("Hotplug-Rule%1").arg(i));
01001 display_config->writeEntry("Outputs", (*it).outputs);
01002 display_config->writeEntry("States", (*it).states);
01003 display_config->writeEntry("Profile", (*it).profileName);
01004 i++;
01005 }
01006 display_config->sync();
01007 delete display_config;
01008 }
01009
01010 bool KRandrSimpleAPI::getDisplayConfigurationEnabled(TQString kde_confdir) {
01011 TQString filename = "displayglobals";
01012 filename.prepend(kde_confdir.append("/"));
01013 KSimpleConfig* display_config = new KSimpleConfig( filename );
01014 display_config->setGroup("General");
01015 bool enabled = display_config->readBoolEntry("EnableDisplayControl", false);
01016 delete display_config;
01017
01018 return enabled;
01019 }
01020
01021 bool KRandrSimpleAPI::getDisplayConfigurationStartupAutoApplyEnabled(TQString kde_confdir) {
01022 TQString filename = "displayglobals";
01023 filename.prepend(kde_confdir.append("/"));
01024 KSimpleConfig* display_config = new KSimpleConfig( filename );
01025 display_config->setGroup("General");
01026 bool applyonstart = display_config->readBoolEntry("ApplySettingsOnStart", false);
01027 delete display_config;
01028
01029 return applyonstart;
01030 }
01031
01032 TQString KRandrSimpleAPI::getDisplayConfigurationStartupAutoApplyName(TQString kde_confdir) {
01033 TQString filename = "displayglobals";
01034 filename.prepend(kde_confdir.append("/"));
01035 KSimpleConfig* display_config = new KSimpleConfig( filename );
01036 display_config->setGroup("General");
01037 TQString profilename = display_config->readEntry("StartupProfileName", "");
01038 delete display_config;
01039
01040 return profilename;
01041 }
01042
01043 void KRandrSimpleAPI::applyHotplugRules(TQString kde_confdir) {
01044 bool enabled = getDisplayConfigurationEnabled(kde_confdir);
01045 if (!enabled) {
01046 return;
01047 }
01048
01049 HotPlugRulesList rules = getHotplugRules(kde_confdir);
01050 TQPtrList<SingleScreenData> screenInfoArray = readCurrentDisplayConfiguration();
01051
01052 int i;
01053 int j;
01054 TQString bestRule;
01055 int bestRuleMatchCount = 0;
01056 SingleScreenData *screendata = NULL;
01057 HotPlugRulesList::Iterator it;
01058 for (it=rules.begin(); it != rules.end(); ++it) {
01059
01060
01061 HotPlugRule rule = *it;
01062 int matchCount = 0;
01063 int numberOfScreens = screenInfoArray.count();
01064 for (i=0;i<numberOfScreens;i++) {
01065 screendata = screenInfoArray.at(i);
01066 for (j=0; j<(*it).outputs.count(); j++) {
01067 if ((*it).outputs[j] != screendata->screenUniqueName) {
01068 continue;
01069 }
01070 if ((*it).states[j] == HotPlugRule::Connected) {
01071 if (screendata->screen_connected) {
01072 matchCount++;
01073 }
01074 }
01075 else if ((*it).states[j] == HotPlugRule::Disconnected) {
01076 if (!screendata->screen_connected) {
01077 matchCount++;
01078 }
01079 }
01080 }
01081 }
01082
01083 if (matchCount > bestRuleMatchCount) {
01084 bestRuleMatchCount = matchCount;
01085 bestRule = rule.profileName;
01086 }
01087 }
01088
01089 destroyScreenInformationObject(screenInfoArray);
01090
01091 if (bestRuleMatchCount > 0) {
01092
01093
01094 applyDisplayConfiguration(bestRule, kde_confdir);
01095 }
01096 }
01097
01098 void KRandrSimpleAPI::applyDisplayGamma(TQPtrList<SingleScreenData> screenInfoArray) {
01099 int i;
01100 Display *randr_display;
01101 XRROutputInfo *output_info;
01102 ScreenInfo *randr_screen_info;
01103 XRRCrtcGamma *gamma;
01104
01105 SingleScreenData *screendata;
01106
01107 if (isValid() == true) {
01108 randr_display = tqt_xdisplay();
01109 randr_screen_info = read_screen_info(randr_display);
01110 for (i = 0; i < screenInfoArray.count(); i++) {
01111 screendata = screenInfoArray.at(i);
01112 output_info = randr_screen_info->outputs[i]->info;
01113 CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
01114 if (!current_crtc) {
01115 continue;
01116 }
01117
01118 int size = XRRGetCrtcGammaSize(randr_display, current_crtc->id);
01119 if (!size) {
01120 continue;
01121 }
01122 gamma = XRRAllocGamma(size);
01123 if (!gamma) {
01124 continue;
01125 }
01126 for (i = 0; i < size; i++) {
01127 if (screendata->gamma_red == 1.0)
01128 gamma->red[i] = i << 8;
01129 else
01130 gamma->red[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_red) * (double)(size-1)*256);
01131
01132 if (screendata->gamma_green == 1.0)
01133 gamma->green[i] = i << 8;
01134 else
01135 gamma->green[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_green) * (double)(size-1)*256);
01136
01137 if (screendata->gamma_blue == 1.0)
01138 gamma->blue[i] = i << 8;
01139 else
01140 gamma->blue[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_blue) * (double)(size-1)*256);
01141 }
01142 XRRSetCrtcGamma(randr_display, current_crtc->id, gamma);
01143 free(gamma);
01144
01145 }
01146 freeScreenInfoStructure(randr_screen_info);
01147 }
01148 }
01149
01150 void KRandrSimpleAPI::applyDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray) {
01151 int i;
01152 Display *randr_display;
01153 XRROutputInfo *output_info;
01154 ScreenInfo *randr_screen_info;
01155 XRRCrtcGamma *gamma;
01156
01157 SingleScreenData *screendata;
01158
01159 if (isValid() == true) {
01160 randr_display = tqt_xdisplay();
01161 randr_screen_info = read_screen_info(randr_display);
01162 for (i = 0; i < screenInfoArray.count(); i++) {
01163 screendata = screenInfoArray.at(i);
01164 output_info = randr_screen_info->outputs[i]->info;
01165 CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
01166 if (!current_crtc) {
01167 continue;
01168 }
01169 if (!screendata->has_dpms) {
01170 continue;
01171 }
01172 if (screendata->enable_dpms) {
01173 DPMSSetTimeouts(randr_display, screendata->dpms_standby_delay, screendata->dpms_suspend_delay, screendata->dpms_off_delay);
01174 DPMSEnable(randr_display);
01175 }
01176 else {
01177 DPMSDisable(randr_display);
01178 }
01179 }
01180 freeScreenInfoStructure(randr_screen_info);
01181 }
01182 }
01183
01184 void KRandrSimpleAPI::freeScreenInfoStructure(ScreenInfo* screen_info) {
01185 int i;
01186
01187 for (i=0; i<screen_info->n_crtc; i++) {
01188 free(screen_info->crtcs[i]);
01189 }
01190 for (i=0; i<screen_info->n_output; i++) {
01191 free(screen_info->outputs[i]);
01192 }
01193 free(screen_info->outputs);
01194 free(screen_info->crtcs);
01195 free(screen_info);
01196 }
01197
01198 TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
01199
01200 int i;
01201 int j;
01202
01203 XRROutputInfo *output_info;
01204 SingleScreenData *screendata;
01205 TQPtrList<SingleScreenData> screenInfoArray;
01206
01207 Display *randr_display;
01208 ScreenInfo *randr_screen_info;
01209
01210
01211 destroyScreenInformationObject(screenInfoArray);
01212
01213 int numberOfScreens = 0;
01214 if (isValid() == true) {
01215 randr_display = tqt_xdisplay();
01216 randr_screen_info = read_screen_info(randr_display);
01217 for (i = 0; i < randr_screen_info->n_output; i++) {
01218 output_info = randr_screen_info->outputs[i]->info;
01219 CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
01220
01221
01222 screendata = new SingleScreenData;
01223 screenInfoArray.append(screendata);
01224 screendata->screenUniqueName = TQString(i18n("%1:%2")).arg(":0").arg(capitalizeString(output_info->name));
01225 screendata->screenFriendlyName = TQString(i18n("%1. %2 output on %3")).arg(i+1).arg(capitalizeString(output_info->name)).arg(":0");
01226 screendata->generic_screen_detected = false;
01227
01228
01229 TQString edid = getEDIDMonitorName(0, output_info->name);
01230 if (!edid.isNull()) {
01231 screendata->screenFriendlyName = TQString(i18n("%1. %2 on %3 on card %4")).arg(i+1).arg(edid).arg(capitalizeString(output_info->name)).arg("0");
01232 }
01233
01234
01235 bool screen_active;
01236 RandRScreen *cur_screen = 0;
01237 if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
01238
01239 screen_active = false;
01240 }
01241 else {
01242 if (randr_screen_info->outputs[i]->cur_crtc) {
01243
01244 screen_active = true;
01245 cur_screen = new RandRScreen(i);
01246 }
01247 else {
01248
01249 screen_active = false;
01250 cur_screen = new RandRScreen(i);
01251 }
01252 }
01253
01254
01255 screendata->has_dpms = 1;
01256 if (screendata->has_dpms) {
01257 CARD16 dpms_standby_delay;
01258 CARD16 dpms_suspend_delay;
01259 CARD16 dpms_off_delay;
01260 screendata->has_dpms = DPMSGetTimeouts(randr_display, &dpms_standby_delay, &dpms_suspend_delay, &dpms_off_delay);
01261 screendata->dpms_standby_delay = dpms_standby_delay;
01262 screendata->dpms_suspend_delay = dpms_suspend_delay;
01263 screendata->dpms_off_delay = dpms_off_delay;
01264 if (screendata->has_dpms) {
01265 CARD16 power_level;
01266 BOOL enable_dpms;
01267 screendata->has_dpms = DPMSInfo(randr_display, &power_level, &enable_dpms);
01268 screendata->enable_dpms = enable_dpms;
01269 }
01270 }
01271 if (!screendata->has_dpms) {
01272 screendata->enable_dpms = false;
01273 screendata->dpms_standby_delay = 0;
01274 screendata->dpms_suspend_delay = 0;
01275 screendata->dpms_off_delay = 0;
01276 }
01277
01278 if (cur_screen) {
01279 screendata->screen_connected = true;
01280 for (int j = 0; j < cur_screen->numSizes(); j++) {
01281 screendata->resolutions.append(i18n("%1 x %2").arg(cur_screen->pixelSize(j).width()).arg(cur_screen->pixelSize(j).height()));
01282 }
01283 screendata->current_resolution_index = 0;
01284 if (current_crtc) {
01285 screendata->current_resolution_index = screendata->resolutions.findIndex(i18n("%1 x %2").arg(current_crtc->info->width).arg(current_crtc->info->height));
01286 }
01287 if (screendata->current_resolution_index < 0) {
01288 screendata->current_resolution_index = cur_screen->proposedSize();
01289 }
01290
01291
01292 TQStringList rr = cur_screen->refreshRates(screendata->current_resolution_index);
01293 for (TQStringList::Iterator it = rr.begin(); it != rr.end(); ++it) {
01294 screendata->refresh_rates.append(*it);
01295 }
01296 screendata->current_refresh_rate_index = cur_screen->proposedRefreshRate();
01297
01298
01299
01300 screendata->color_depths.append(i18n("Default"));
01301 screendata->current_color_depth_index = 0;
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311 screendata->rotations.append(i18n(ROTATION_0_DEGREES_STRING));
01312 screendata->rotations.append(i18n(ROTATION_90_DEGREES_STRING));
01313 screendata->rotations.append(i18n(ROTATION_180_DEGREES_STRING));
01314 screendata->rotations.append(i18n(ROTATION_270_DEGREES_STRING));
01315 screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0);
01316 if (screendata->supports_transformations) {
01317 screendata->current_orientation_mask = cur_screen->proposedRotation();
01318 switch (screendata->current_orientation_mask & RandRScreen::RotateMask) {
01319 case RandRScreen::Rotate0:
01320 screendata->current_rotation_index = 0;
01321 break;
01322 case RandRScreen::Rotate90:
01323 screendata->current_rotation_index = 1;
01324 break;
01325 case RandRScreen::Rotate180:
01326 screendata->current_rotation_index = 2;
01327 break;
01328 case RandRScreen::Rotate270:
01329 screendata->current_rotation_index = 3;
01330 break;
01331 default:
01332
01333 Q_ASSERT(screendata->current_orientation_mask & RandRScreen::RotateMask);
01334 screendata->current_rotation_index = 0;
01335 break;
01336 }
01337 screendata->has_x_flip = (screendata->current_orientation_mask & RandRScreen::ReflectX);
01338 screendata->has_y_flip = (screendata->current_orientation_mask & RandRScreen::ReflectY);
01339 }
01340 else {
01341 screendata->has_x_flip = false;
01342 screendata->has_y_flip = false;
01343 screendata->current_rotation_index = 0;
01344 }
01345
01346
01347 RROutput primaryoutput = XRRGetOutputPrimary(tqt_xdisplay(), DefaultRootWindow(tqt_xdisplay()));
01348 if (primaryoutput == randr_screen_info->outputs[i]->id) {
01349 screendata->is_primary = false;
01350 }
01351 else {
01352 screendata->is_primary = true;
01353 }
01354 screendata->is_extended = screen_active;
01355 if (!screendata->is_extended) {
01356 screendata->is_primary = false;
01357 }
01358
01359
01360 screendata->absolute_x_position = 0;
01361 screendata->absolute_y_position = 0;
01362 if (current_crtc) {
01363 screendata->absolute_x_position = current_crtc->info->x;
01364 screendata->absolute_y_position = current_crtc->info->y;
01365 }
01366
01367
01368 screendata->current_x_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).width();
01369 screendata->current_y_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).height();
01370
01371
01372
01373
01374
01375
01376
01377 screendata->gamma_red = 2.2;
01378 screendata->gamma_green = 2.2;
01379 screendata->gamma_blue = 2.2;
01380 if (current_crtc) {
01381
01382 int slot = 7;
01383 int size = XRRGetCrtcGammaSize(randr_display, current_crtc->id);
01384 if(size>0) {
01385 XRRCrtcGamma *gammastruct = XRRGetCrtcGamma (randr_display, current_crtc->id);
01386 screendata->gamma_red = log(gammastruct->red[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
01387 screendata->gamma_green = log(gammastruct->green[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
01388 screendata->gamma_blue = log(gammastruct->blue[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
01389 }
01390 }
01391
01392 screendata->gamma_red = floorf(screendata->gamma_red * 10 + 0.5) / 10;
01393 screendata->gamma_green = floorf(screendata->gamma_green * 10 + 0.5) / 10;
01394 screendata->gamma_blue = floorf(screendata->gamma_blue * 10 + 0.5) / 10;
01395
01396 delete cur_screen;
01397 }
01398 else {
01399
01400 screendata->screenFriendlyName = screendata->screenFriendlyName + TQString(" (") + i18n("disconnected") + TQString(")");
01401 screendata->screen_connected = false;
01402
01403 screendata->resolutions = i18n("Default");
01404 screendata->refresh_rates = i18n("Default");
01405 screendata->color_depths = i18n("Default");
01406 screendata->rotations = i18n("N/A");
01407
01408 screendata->current_resolution_index = 0;
01409 screendata->current_refresh_rate_index = 0;
01410 screendata->current_color_depth_index = 0;
01411
01412 screendata->gamma_red = 2.2;
01413 screendata->gamma_green = 2.2;
01414 screendata->gamma_blue = 2.2;
01415
01416 screendata->current_rotation_index = 0;
01417 screendata->current_orientation_mask = 0;
01418 screendata->has_x_flip = false;
01419 screendata->has_y_flip = false;
01420 screendata->supports_transformations = false;
01421
01422 screendata->is_primary = false;
01423 screendata->is_extended = false;
01424 screendata->absolute_x_position = 0;
01425 screendata->absolute_y_position = 0;
01426 screendata->current_x_pixel_count = 640;
01427 screendata->current_y_pixel_count = 480;
01428 }
01429
01430
01431 numberOfScreens++;
01432 }
01433
01434 freeScreenInfoStructure(randr_screen_info);
01435 }
01436 else {
01437 screendata = new SingleScreenData;
01438 screenInfoArray.append(screendata);
01439
01440
01441 screendata->screenFriendlyName = i18n("Default output on generic video card");
01442 screendata->generic_screen_detected = true;
01443 screendata->screen_connected = true;
01444
01445 screendata->resolutions = i18n("Default");
01446 screendata->refresh_rates = i18n("Default");
01447 screendata->color_depths = i18n("Default");
01448 screendata->rotations = i18n("N/A");
01449
01450 screendata->current_resolution_index = 0;
01451 screendata->current_refresh_rate_index = 0;
01452 screendata->current_color_depth_index = 0;
01453
01454 screendata->gamma_red = 2.2;
01455 screendata->gamma_green = 2.2;
01456 screendata->gamma_blue = 2.2;
01457
01458 screendata->current_rotation_index = 0;
01459 screendata->current_orientation_mask = 0;
01460 screendata->has_x_flip = false;
01461 screendata->has_y_flip = false;
01462 screendata->supports_transformations = false;
01463
01464 screendata->is_primary = true;
01465 screendata->is_extended = true;
01466 screendata->absolute_x_position = 0;
01467 screendata->absolute_y_position = 0;
01468 screendata->current_x_pixel_count = 640;
01469 screendata->current_y_pixel_count = 480;
01470
01471 numberOfScreens++;
01472 }
01473
01474 bool primary_set = false;
01475 for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
01476 if (screendata->is_primary) {
01477 primary_set = true;
01478 break;
01479 }
01480 }
01481
01482 Q_ASSERT(primary_set);
01483 if (!primary_set) {
01484
01485
01486 screendata = screenInfoArray.at(0);
01487 screendata->is_primary = true;
01488 }
01489
01490 return screenInfoArray;
01491 }
01492
01493 TQString KRandrSimpleAPI::clearIccConfiguration() {
01494
01495 TQString icc_command;
01496 FILE *pipe_xcalib;
01497 char xcalib_result[2048];
01498 int i;
01499 xcalib_result[0]=0;
01500
01501 icc_command = TQString("xcalib -c");
01502 if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
01503 {
01504 printf("Xcalib pipe error [xcalib clear]\n");
01505 }
01506 else {
01507 if (fgets(xcalib_result, 2048, pipe_xcalib)) {
01508 pclose(pipe_xcalib);
01509 for (i=1;i<2048;i++) {
01510 if (xcalib_result[i] == 0) {
01511 xcalib_result[i-1]=0;
01512 i=2048;
01513 }
01514 }
01515 if (strlen(xcalib_result) > 2) {
01516 return xcalib_result;
01517 }
01518 }
01519 else {
01520 return "";
01521 }
01522 }
01523 return "";
01524 }
01525
01526 ScreenInfo* KRandrSimpleAPI::read_screen_info (Display *display)
01527 {
01528 return internal_read_screen_info(display);
01529 }
01530
01531 int KRandrSimpleAPI::set_screen_size (ScreenInfo *screen_info)
01532 {
01533 return internal_set_screen_size(screen_info);
01534 }
01535
01536 void KRandrSimpleAPI::output_auto (ScreenInfo *screen_info, OutputInfo *output_info)
01537 {
01538 internal_output_auto (screen_info, output_info);
01539 }
01540
01541 void KRandrSimpleAPI::output_off(ScreenInfo *screen_info, OutputInfo *output)
01542 {
01543 internal_output_off(screen_info, output);
01544 }
01545
01546 CrtcInfo* KRandrSimpleAPI::auto_find_crtc (ScreenInfo *screen_info, OutputInfo *output_info)
01547 {
01548 return internal_auto_find_crtc (screen_info, output_info);
01549 }
01550
01551 XRRModeInfo *KRandrSimpleAPI::find_mode_by_xid (ScreenInfo *screen_info, RRMode mode_id)
01552 {
01553 return internal_find_mode_by_xid (screen_info, mode_id);
01554 }
01555
01556 int KRandrSimpleAPI::mode_height (XRRModeInfo *mode_info, Rotation rotation)
01557 {
01558 return internal_mode_height (mode_info, rotation);
01559 }
01560
01561 int KRandrSimpleAPI::mode_width (XRRModeInfo *mode_info, Rotation rotation)
01562 {
01563 return internal_mode_width (mode_info, rotation);
01564 }
01565
01566 int KRandrSimpleAPI::get_width_by_output_id (ScreenInfo *screen_info, RROutput output_id)
01567 {
01568 return internal_get_width_by_output_id (screen_info, output_id);
01569 }
01570
01571 int KRandrSimpleAPI::get_height_by_output_id (ScreenInfo *screen_info, RROutput output_id)
01572 {
01573 return internal_get_height_by_output_id (screen_info, output_id);
01574 }
01575
01576 char *KRandrSimpleAPI::get_output_name (ScreenInfo *screen_info, RROutput id)
01577 {
01578 return internal_get_output_name (screen_info, id);
01579 }
01580
01581 Status KRandrSimpleAPI::crtc_apply (CrtcInfo *crtc_info)
01582 {
01583 return internal_crtc_apply (crtc_info);
01584 }
01585
01586 Status KRandrSimpleAPI::crtc_disable (CrtcInfo *crtc)
01587 {
01588 return internal_crtc_disable (crtc);
01589 }
01590
01591 int KRandrSimpleAPI::main_low_apply (ScreenInfo *screen_info)
01592 {
01593 return internal_main_low_apply (screen_info);
01594 }
01595
01596 void KRandrSimpleAPI::set_primary_output (ScreenInfo *screen_info, RROutput output_id)
01597 {
01598 internal_output_set_primary(screen_info, output_id);
01599 }
01600
01601 bool KRandrSimpleAPI::kRandrHasRandr(void)
01602 {
01603 return isValid();
01604 }
01605
01606 const char *KRandrSimpleAPI::kRandrVersion(void)
01607 {
01608 return "0.9.5";
01609 }
01610
01611 const char *KRandrSimpleAPI::kRandrCopyright(void)
01612 {
01613 return "LibKRandr 0.9.5 (C)2010 Timothy Pearson <kb9vqf@pearsoncomputing.net>. U.S.A.";
01614 }
01615
01616
01617
01618
01619
01620
01621 const char *kRandrVersion(void)
01622 {
01623 return KRandrSimpleAPI::kRandrVersion();
01624 }
01625
01626 const char *kRandrCopyright(void)
01627 {
01628 return KRandrSimpleAPI::kRandrCopyright();
01629 }
01630