• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • krandr
 

krandr

  • krandr
libkrandr.cc
1 /* libkrandr.cc - class KRandr that makes it easy to use XRandr in KDE
2  This file is part of KRandr 0.9.5
3  Copyright (C) 2010 Timothy Pearson
4  LibKRandr's homepage : http://www.trinitydesktop.org
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21  Send comments and bug fixes to Timothy Pearson <kb9vqf@pearsoncomputing.net>
22 
23 ***************************************************************************/
24 
25 #include <tqtimer.h>
26 #include <tqstringlist.h>
27 #include <tqregexp.h>
28 
29 #include <klocale.h>
30 #include <kmessagebox.h>
31 #include <kapplication.h>
32 
33 #include <stdlib.h>
34 #include <cmath>
35 
36 #include "libkrandr.h"
37 
38 #include <X11/extensions/dpms.h>
39 
40 // FIXME
41 // For now, just use the standalone xrandr program to apply the display settings
42 #define USE_XRANDR_PROGRAM
43 
44 // This routine is courtsey of an answer on "Stack Overflow"
45 // It takes an LSB-first int and makes it an MSB-first int (or vice versa)
46 unsigned int reverse_bits(unsigned int x)
47 {
48  x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
49  x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
50  x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
51  x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
52  return((x >> 16) | (x << 16));
53 }
54 
55 // This routine returns the output of an arbitrary Bash command
56 TQString exec(const char * cmd) {
57  TQString bashcommand = cmd;
58  bashcommand = bashcommand.replace("\"", "\\\"");
59  bashcommand = TQString("/bin/bash -c \"%1\" 2>&1").arg(bashcommand);
60  FILE* pipe = popen(bashcommand.ascii(), "r");
61  if (!pipe) return "ERROR";
62  char buffer[128];
63  TQString result = "";
64  while(!feof(pipe)) {
65  if(fgets(buffer, 128, pipe) != NULL) {
66  result += buffer;
67  }
68  }
69  pclose(pipe);
70  result.remove(result.length(), 1);
71  return result;
72 }
73 
74 TQString capitalizeString(TQString in) {
75  return in.left(1).upper() + in.right(in.length()-1);
76 }
77 
78 TQString KRandrSimpleAPI::getIccFileName(TQString profileName, TQString screenName, TQString kde_confdir) {
79  KSimpleConfig *t_config = NULL;
80  KSimpleConfig *t_systemconfig = NULL;
81  int t_numberOfProfiles;
82  TQStringList t_cfgProfiles;
83  TQString retval;
84 
85  if ((profileName != NULL) && (profileName != "")) {
86  t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
87  t_config->setGroup(NULL);
88  if (t_config->readBoolEntry("EnableICC", false) == true) {
89  t_config->setGroup(profileName);
90  retval = t_config->readEntry(screenName);
91  }
92  else {
93  retval = "";
94  }
95  delete t_config;
96  }
97  else {
98  t_systemconfig = new KSimpleConfig( kde_confdir + TQString("/kicc/kiccconfigrc") );
99  t_systemconfig->setGroup(NULL);
100  if (t_systemconfig->readBoolEntry("EnableICC", false) == true) {
101  retval = t_systemconfig->readEntry("ICCFile");
102  }
103  else {
104  retval = "";
105  }
106  delete t_systemconfig;
107  }
108 
109  return retval;
110 }
111 
112 TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
113  int i;
114  int j;
115  Display *randr_display;
116  ScreenInfo *randr_screen_info;
117  XRROutputInfo *output_info;
118 
119  int screenNumber = 0;
120 
121  if (fileName != "") {
122  // FIXME
123  // This should use the RRSetCrtcGamma function when available
124  // That is the only way to get proper setting when two output are active at the same time
125  // (otherwise in clone mode only one screen is available)
126 
127  // HACK
128  // For now, simply exit with no changes if screenName is not an active output
129 
130  if (isValid() == true) {
131  screenNumber = -1;
132  randr_display = qt_xdisplay();
133  randr_screen_info = read_screen_info(randr_display);
134  if (randr_screen_info == NULL) {
135  return "";
136  }
137  j=0;
138  for (i = 0; i < randr_screen_info->n_output; i++) {
139  output_info = randr_screen_info->outputs[i]->info;
140  // Look for ON outputs...
141  if (!randr_screen_info->outputs[i]->cur_crtc) {
142  continue;
143  }
144  // ...that are connected
145  if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
146  continue;
147  }
148  if (output_info->name == screenName) {
149  screenNumber = j;
150  }
151  j++;
152  }
153  freeScreenInfoStructure(randr_screen_info);
154  }
155 
156  if (screenNumber >= 0) {
157  // Apply ICC settings with XCalib
158  TQString icc_command;
159  FILE *pipe_xcalib;
160  char xcalib_result[2048];
161  int i;
162  xcalib_result[0]=0;
163 
164  icc_command = TQString("xcalib \"%1\"").arg(fileName);
165  if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
166  {
167  printf("Xcalib pipe error\n [xcalib apply]");
168  }
169  else {
170  fgets(xcalib_result, 2048, pipe_xcalib);
171  pclose(pipe_xcalib);
172  for (i=1;i<2048;i++) {
173  if (xcalib_result[i] == 0) {
174  xcalib_result[i-1]=0;
175  i=2048;
176  }
177  }
178  if (strlen(xcalib_result) > 2) {
179  return xcalib_result;
180  }
181  }
182  }
183  }
184  else {
185  // Reset ICC profile on this screen
186 
187  // FIXME
188  // This should use the RRSetCrtcGamma function when available
189  // That is the only way to get proper setting when two output are active at the same time
190  // (otherwise in clone mode only one screen is available)
191 
192  // HACK
193  // For now, simply exit with no changes if screenName is not an active output
194 
195  if (isValid() == true) {
196  screenNumber = -1;
197  randr_display = qt_xdisplay();
198  randr_screen_info = read_screen_info(randr_display);
199  if (randr_screen_info == NULL) {
200  return "";
201  }
202  j=0;
203  for (i = 0; i < randr_screen_info->n_output; i++) {
204  output_info = randr_screen_info->outputs[i]->info;
205  // Look for ON outputs...
206  if (!randr_screen_info->outputs[i]->cur_crtc) {
207  continue;
208  }
209  // ...that are connected
210  if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
211  continue;
212  }
213  if (output_info->name == screenName) {
214  screenNumber = j;
215  }
216  j++;
217  }
218  freeScreenInfoStructure(randr_screen_info);
219  }
220 
221  if (screenNumber >= 0) {
222  // Apply ICC settings with XCalib
223  TQString icc_command;
224  FILE *pipe_xcalib;
225  char xcalib_result[2048];
226  int i;
227  xcalib_result[0]=0;
228 
229  icc_command = TQString("xcalib -c");
230  if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
231  {
232  printf("Xcalib pipe error\n [xcalib clear]");
233  }
234  else {
235  fgets(xcalib_result, 2048, pipe_xcalib);
236  pclose(pipe_xcalib);
237  for (i=1;i<2048;i++) {
238  if (xcalib_result[i] == 0) {
239  xcalib_result[i-1]=0;
240  i=2048;
241  }
242  }
243  if (strlen(xcalib_result) > 2) {
244  return xcalib_result;
245  }
246  }
247  }
248  }
249  return "";
250 }
251 
252 TQString KRandrSimpleAPI::applyIccConfiguration(TQString profileName, TQString kde_confdir) {
253  int i;
254  Display *randr_display;
255  ScreenInfo *randr_screen_info;
256  XRROutputInfo *output_info;
257  KSimpleConfig *t_config;
258 
259  int screenNumber = 0;
260  TQString errorstr = "";
261 
262  t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
263 
264  // Find all screens
265  if (isValid() == true) {
266  randr_display = qt_xdisplay();
267  randr_screen_info = read_screen_info(randr_display);
268  if (randr_screen_info == NULL) {
269  return "";
270  }
271  for (i = 0; i < randr_screen_info->n_output; i++) {
272  output_info = randr_screen_info->outputs[i]->info;
273  errorstr = applyIccFile(output_info->name, getIccFileName(profileName, output_info->name, kde_confdir));
274  if (errorstr != "") {
275  return errorstr;
276  }
277  }
278  freeScreenInfoStructure(randr_screen_info);
279  }
280  else {
281  return applyIccFile(getIccFileName(profileName, "Default", kde_confdir), "Default");
282  }
283 
284  t_config->writeEntry("CurrentProfile", profileName);
285  t_config->sync();
286  delete t_config;
287 
288  return "";
289 }
290 
291 TQString KRandrSimpleAPI::getEDIDMonitorName(int card, TQString displayname) {
292  TQString edid;
293  TQByteArray binaryedid = getEDID(card, displayname);
294  if (binaryedid.isNull())
295  return TQString();
296 
297  // Get the manufacturer ID
298  unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
299  unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
300  unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
301  TQChar qletter_1 = TQChar(letter_1);
302  TQChar qletter_2 = TQChar(letter_2);
303  TQChar qletter_3 = TQChar(letter_3);
304  TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
305 
306  // Get the model ID
307  unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
308  // Reverse the bit order
309  unsigned int model_id = reverse_bits(raw_model_id);
310 
311  // Try to get the model name
312  bool has_friendly_name = false;
313  unsigned char descriptor_block[18];
314  int i;
315  for (i=72;i<90;i++) {
316  descriptor_block[i-72] = binaryedid[i] & 0xFF;
317  }
318  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
319  for (i=90;i<108;i++) {
320  descriptor_block[i-90] = binaryedid[i] & 0xFF;
321  }
322  if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
323  for (i=108;i<126;i++) {
324  descriptor_block[i-108] = binaryedid[i] & 0xFF;
325  }
326  }
327  }
328 
329  TQString monitor_name;
330  if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
331  char* pos = strchr((char *)(descriptor_block+5), '\n');
332  if (pos) {
333  *pos = 0;
334  has_friendly_name = true;
335  monitor_name = TQString((char *)(descriptor_block+5));
336  }
337  else {
338  has_friendly_name = false;
339  }
340  }
341 
342  // [FIXME]
343  // Look up manudacturer names if possible!
344 
345  if (has_friendly_name)
346  edid = TQString("%1 %2").arg(manufacturer_id).arg(monitor_name);
347  else
348  edid = TQString("%1 0x%2").arg(manufacturer_id).arg(model_id, 0, 16);
349 
350  return edid;
351 }
352 
353 TQByteArray KRandrSimpleAPI::getEDID(int card, TQString displayname) {
354  TQFile file(TQString("/sys/class/drm/card%1-%2/edid").arg(card).arg(displayname));
355  if (!file.open (IO_ReadOnly))
356  return TQByteArray();
357  TQByteArray binaryedid = file.readAll();
358  file.close();
359  return binaryedid;
360 }
361 
362 TQString KRandrSimpleAPI::getCurrentProfile () {
363  TQString profileName;
364  KSimpleConfig *t_config;
365 
366  t_config = new KSimpleConfig( TQString::fromLatin1( "kiccconfigrc" ));
367  profileName = t_config->readEntry("CurrentProfile");
368  delete t_config;
369  return profileName;
370 }
371 
372 TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir) {
373  // Apply ICC settings with XCalib
374  TQString icc_command;
375  FILE *pipe_xcalib;
376  char xcalib_result[2048];
377  int i;
378  xcalib_result[0]=0;
379 
380  icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir));
381  if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
382  {
383  printf("Xcalib pipe error [xcalib apply]\n");
384  }
385  else {
386  fgets(xcalib_result, 2048, pipe_xcalib);
387  pclose(pipe_xcalib);
388  for (i=1;i<2048;i++) {
389  if (xcalib_result[i] == 0) {
390  xcalib_result[i-1]=0;
391  i=2048;
392  }
393  }
394  if (strlen(xcalib_result) > 2) {
395  return xcalib_result;
396  }
397  }
398  return "";
399 }
400 
401 void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString profilename, TQString kde_confdir, TQPtrList<SingleScreenData> screenInfoArray) {
402  int i;
403 
404  TQString filename;
405 
406  filename = "displayglobals";
407  filename.prepend(kde_confdir.append("/"));
408  KSimpleConfig* display_config = new KSimpleConfig( filename );
409  display_config->setGroup("General");
410  display_config->writeEntry("ApplySettingsOnStart", enable);
411  display_config->sync();
412  delete display_config;
413 
414  filename = profilename;
415  if (filename == "")
416  filename = "default";
417  filename.prepend(kde_confdir.append("/displayconfig/"));
418 
419  display_config = new KSimpleConfig( filename );
420 
421  i=0;
422  SingleScreenData *screendata;
423  for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
424  display_config->setGroup(TQString("SCREEN %1").arg(i));
425  display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName);
426  display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected);
427  display_config->writeEntry("ScreenConnected", screendata->screen_connected);
428  display_config->writeEntry("Resolutions", screendata->resolutions);
429  display_config->writeEntry("RefreshRates", screendata->refresh_rates);
430  display_config->writeEntry("ColorDepths", screendata->color_depths);
431  display_config->writeEntry("AvailableRotations", screendata->rotations);
432  display_config->writeEntry("CurrentResolution", screendata->current_resolution_index);
433  display_config->writeEntry("CurrentRefreshRate", screendata->current_refresh_rate_index);
434  display_config->writeEntry("CurrentColorDepth", screendata->current_color_depth_index);
435  display_config->writeEntry("CurrentRotation", screendata->current_rotation_index);
436  display_config->writeEntry("CurrentOrientiation", screendata->current_orientation_mask);
437  display_config->writeEntry("GammaRed", screendata->gamma_red);
438  display_config->writeEntry("GammaGreen", screendata->gamma_green);
439  display_config->writeEntry("GammaBlue", screendata->gamma_blue);
440  display_config->writeEntry("CurrentXFlip", screendata->has_x_flip);
441  display_config->writeEntry("CurrentYFlip", screendata->has_y_flip);
442  display_config->writeEntry("SupportsTransformation", screendata->supports_transformations);
443  display_config->writeEntry("IsPrimary", screendata->is_primary);
444  display_config->writeEntry("IsExtended", screendata->is_extended);
445  display_config->writeEntry("AbsXPos", screendata->absolute_x_position);
446  display_config->writeEntry("AbsYPos", screendata->absolute_y_position);
447  display_config->writeEntry("CurrentXPixelCount", screendata->current_x_pixel_count);
448  display_config->writeEntry("CurrentYPixelCount", screendata->current_y_pixel_count);
449  display_config->writeEntry("HasDPMS", screendata->has_dpms);
450  display_config->writeEntry("EnableDPMS", screendata->enable_dpms);
451  display_config->writeEntry("DPMSStandbyDelay", screendata->dpms_standby_delay);
452  display_config->writeEntry("DPMSSuspendDelay", screendata->dpms_suspend_delay);
453  display_config->writeEntry("DPMSPowerDownDelay", screendata->dpms_off_delay);
454  i++;
455  }
456 
457  display_config->sync();
458  delete display_config;
459 }
460 
461 TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) {
462  TQPoint ret;
463 
464  TQString filename = "displayglobals";
465  filename.prepend(kde_confdir.append("/"));
466  KSimpleConfig* display_config = new KSimpleConfig( filename );
467  display_config->setGroup("General");
468  bool enabled = display_config->readBoolEntry("ApplySettingsOnStart", false);
469  delete display_config;
470 
471  if (enabled) {
472  TQPtrList<SingleScreenData> screenInfoArray;
473  screenInfoArray = loadSystemwideDisplayConfiguration(profilename, kde_confdir);
474  if (screenInfoArray.count() > 0) {
475  applySystemwideDisplayConfiguration(screenInfoArray, FALSE, kde_confdir);
476  }
477  destroyScreenInformationObject(screenInfoArray);
478  screenInfoArray = readCurrentDisplayConfiguration();
479  ensureMonitorDataConsistency(screenInfoArray);
480  ret = primaryScreenOffsetFromTLC(screenInfoArray);
481  destroyScreenInformationObject(screenInfoArray);
482  }
483 
484  return ret;
485 }
486 
487 TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) {
488  int i;
489 
490  TQString filename;
491  filename = profilename;
492  if (filename == "")
493  filename = "default";
494  filename.prepend(kde_confdir.append("/displayconfig/"));
495 
496  KSimpleConfig* display_config = new KSimpleConfig( filename );
497 
498  TQStringList grouplist = display_config->groupList();
499  SingleScreenData *screendata;
500  TQPtrList<SingleScreenData> screenInfoArray;
501  for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) {
502  if ((*it).startsWith("SCREEN ")) {
503  display_config->setGroup(*it);
504  i = ((*it).remove("SCREEN ")).toInt();
505  screendata = new SingleScreenData;
506  screenInfoArray.append(screendata);
507  screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName");
508  screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected");
509  screendata->screen_connected = display_config->readBoolEntry("ScreenConnected");
510  screendata->resolutions = display_config->readListEntry("Resolutions");
511  screendata->refresh_rates = display_config->readListEntry("RefreshRates");
512  screendata->color_depths = display_config->readListEntry("ColorDepths");
513  screendata->rotations = display_config->readListEntry("AvailableRotations");
514  screendata->current_resolution_index = display_config->readNumEntry("CurrentResolution");
515  screendata->current_refresh_rate_index = display_config->readNumEntry("CurrentRefreshRate");
516  screendata->current_color_depth_index = display_config->readNumEntry("CurrentColorDepth");
517  screendata->current_rotation_index = display_config->readNumEntry("CurrentRotation");
518  screendata->current_orientation_mask = display_config->readNumEntry("CurrentOrientiation");
519  screendata->gamma_red = display_config->readDoubleNumEntry("GammaRed");
520  screendata->gamma_green = display_config->readDoubleNumEntry("GammaGreen");
521  screendata->gamma_blue = display_config->readDoubleNumEntry("GammaBlue");
522  screendata->has_x_flip = display_config->readBoolEntry("CurrentXFlip");
523  screendata->has_y_flip = display_config->readBoolEntry("CurrentYFlip");
524  screendata->supports_transformations = display_config->readBoolEntry("SupportsTransformation");
525  screendata->is_primary = display_config->readBoolEntry("IsPrimary");
526  screendata->is_extended = display_config->readBoolEntry("IsExtended");
527  screendata->absolute_x_position = display_config->readNumEntry("AbsXPos");
528  screendata->absolute_y_position = display_config->readNumEntry("AbsYPos");
529  screendata->current_x_pixel_count = display_config->readNumEntry("CurrentXPixelCount");
530  screendata->current_y_pixel_count = display_config->readNumEntry("CurrentYPixelCount");
531  screendata->has_dpms = display_config->readBoolEntry("HasDPMS");
532  screendata->enable_dpms = display_config->readBoolEntry("EnableDPMS");
533  screendata->dpms_standby_delay = display_config->readNumEntry("DPMSStandbyDelay");
534  screendata->dpms_suspend_delay = display_config->readNumEntry("DPMSSuspendDelay");
535  screendata->dpms_off_delay = display_config->readNumEntry("DPMSPowerDownDelay");
536  }
537  }
538 
539  delete display_config;
540 
541  return screenInfoArray;
542 }
543 
544 int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
545  int rotationFlags = 0;
546  TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
547  if (rotationDesired == "Normal") {
548  rotationFlags = rotationFlags | RandRScreen::Rotate0;
549  }
550  else if (rotationDesired == "Rotate 90 degrees") {
551  rotationFlags = rotationFlags | RandRScreen::Rotate90;
552  }
553  else if (rotationDesired == "Rotate 180 degrees") {
554  rotationFlags = rotationFlags | RandRScreen::Rotate180;
555  }
556  else if (rotationDesired == "Rotate 270 degrees") {
557  rotationFlags = rotationFlags | RandRScreen::Rotate270;
558  }
559  if (screendata->has_x_flip) {
560  rotationFlags = rotationFlags | RandRScreen::ReflectX;
561  }
562  if (screendata->has_y_flip) {
563  rotationFlags = rotationFlags | RandRScreen::ReflectY;
564  }
565  return rotationFlags;
566 }
567 
568 #define USE_XRANDR_PROGRAM
569 
570 bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test, TQString kde_confdir) {
571  int i;
572  int j;
573  bool accepted = true;
574  Display *randr_display;
575  XRROutputInfo *output_info;
576  ScreenInfo *randr_screen_info;
577 
578  SingleScreenData *screendata;
579 
580  TQPtrList<SingleScreenData> oldconfig;
581  if (test == TRUE) {
582  oldconfig = readCurrentDisplayConfiguration();
583  }
584 
585  if (isValid() == true) {
586 #ifdef USE_XRANDR_PROGRAM
587  // Assemble the command string for xrandr
588  TQString command;
589  command = "xrandr";
590 
591  randr_display = qt_xdisplay();
592  randr_screen_info = read_screen_info(randr_display);
593  for (i = 0; i < screenInfoArray.count(); i++) {
594  screendata = screenInfoArray.at(i);
595  if (screendata) {
596  output_info = randr_screen_info->outputs[i]->info;
597  command.append(" --output ").append(output_info->name);
598  if (screendata->is_primary || screendata->is_extended) {
599  command.append(TQString(" --mode %1x%2").arg(screendata->current_x_pixel_count).arg(screendata->current_y_pixel_count));
600  command.append(TQString(" --pos %1x%2").arg(screendata->absolute_x_position).arg(screendata->absolute_y_position));
601  command.append(TQString(" --refresh %1").arg(atoi((*screendata->refresh_rates.at(screendata->current_refresh_rate_index)).ascii())));
602  command.append(TQString(" --gamma %1:%2:%3").arg(screendata->gamma_red).arg(screendata->gamma_green).arg(screendata->gamma_blue));
603  if (screendata->current_rotation_index == 0) command.append(" --rotate ").append("normal");
604  if (screendata->current_rotation_index == 1) command.append(" --rotate ").append("left");
605  if (screendata->current_rotation_index == 2) command.append(" --rotate ").append("inverted");
606  if (screendata->current_rotation_index == 3) command.append(" --rotate ").append("right");
607  if ((screendata->has_x_flip == 0) && (screendata->has_y_flip == 0)) command.append(" --reflect ").append("normal");
608  if ((screendata->has_x_flip == 1) && (screendata->has_y_flip == 0)) command.append(" --reflect ").append("x");
609  if ((screendata->has_x_flip == 0) && (screendata->has_y_flip == 1)) command.append(" --reflect ").append("y");
610  if ((screendata->has_x_flip == 1) && (screendata->has_y_flip == 1)) command.append(" --reflect ").append("xy");
611  if (screendata->is_primary) {
612  command.append(" --primary");
613  }
614  }
615  else {
616  command.append(" --off");
617  }
618  }
619  else {
620  printf("[WARNING] Unable to find configuration for monitor %d; settings may not be correctly applied...\n", i); fflush(stdout);
621  }
622  }
623  freeScreenInfoStructure(randr_screen_info);
624 
625  TQString xrandr_command_output = exec(command.ascii());
626  xrandr_command_output = xrandr_command_output.stripWhiteSpace();
627  if (test) {
628  // In case gamma settings is not supported, try again without '--gamma' parameter
629  if (xrandr_command_output == "xrandr: Gamma size is 0.") {
630  command = command.replace(TQRegExp("--gamma [0-9\\.]*:[0-9\\.]*:[0-9\\.]*"), "");
631  xrandr_command_output = exec(command.ascii());
632  xrandr_command_output = xrandr_command_output.stripWhiteSpace();
633  }
634 
635  if(xrandr_command_output.startsWith("xrandr: Failed to get size of gamma for output")) {
636  KMessageBox::sorry(0, xrandr_command_output, i18n("Setting gamma failed."));
637  } else if (xrandr_command_output != "") {
638  applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir);
639  accepted = false;
640  destroyScreenInformationObject(oldconfig);
641  KMessageBox::sorry(0, xrandr_command_output, i18n("XRandR encountered a problem"));
642  return accepted;
643  }
644  }
645 
646  // HACK
647  // This is needed because Qt does not properly generate screen
648  // resize events when switching screens, so KDE gets stuck in the old resolution
649  // This only seems to happen with more than one screen, so check for that condition...
650  // FIXME: This also only occurs when the primary display has been changed
651  // FIXME: Check for that condition as well!
652  if (kapp->desktop()->numScreens() > 1) {
653  for (i = 0; i < screenInfoArray.count(); i++) {
654  screendata = screenInfoArray.at(i);
655  if (screendata->is_primary == true) {
656  kapp->desktop()->emitResizedSignal(i);
657  }
658  }
659  }
660 #else
661  randr_display = qt_xdisplay();
662  randr_screen_info = read_screen_info(randr_display);
663  // Turn off all displays
664  for (i = 0; i < screenInfoArray.count(); i++) {
665  screendata = screenInfoArray.at(i);
666  output_info = randr_screen_info->outputs[i]->info;
667 
668  randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
669  randr_screen_info->cur_output = randr_screen_info->outputs[i];
670  randr_screen_info->cur_output->auto_set = 0;
671  randr_screen_info->cur_output->off_set = 1;
672  output_off (randr_screen_info, randr_screen_info->cur_output);
673  j=main_low_apply(randr_screen_info);
674  }
675  freeScreenInfoStructure(randr_screen_info);
676  randr_screen_info = read_screen_info(randr_display);
677  // Turn on the primary display
678  for (i = 0; i < screenInfoArray.count(); i++) {
679  screendata = screenInfoArray.at(i);
680  output_info = randr_screen_info->outputs[i]->info;
681 
682  if (screendata->is_primary == true) {
683  randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
684  randr_screen_info->cur_output = randr_screen_info->outputs[i];
685  randr_screen_info->cur_output->auto_set = 1;
686  randr_screen_info->cur_output->off_set = 0;
687  output_auto (randr_screen_info, randr_screen_info->cur_output);
688  j=main_low_apply(randr_screen_info);
689  }
690  }
691  freeScreenInfoStructure(randr_screen_info);
692  // Handle the remaining displays
693  randr_screen_info = read_screen_info(randr_display);
694  for (i = 0; i < screenInfoArray.count(); i++) {
695  screendata = screenInfoArray.at(i);
696  output_info = randr_screen_info->outputs[i]->info;
697 
698  // Activate or deactivate the screens as necessary
699  randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
700  randr_screen_info->cur_output = randr_screen_info->outputs[i];
701  if (screendata->is_primary == false) {
702  if (screendata->is_primary || screendata->is_extended) {
703  randr_screen_info->cur_output->auto_set = 1;
704  randr_screen_info->cur_output->off_set = 0;
705  output_auto (randr_screen_info, randr_screen_info->cur_output);
706  j=main_low_apply(randr_screen_info);
707  }
708  else {
709  randr_screen_info->cur_output->auto_set = 0;
710  randr_screen_info->cur_output->off_set = 1;
711  output_off (randr_screen_info, randr_screen_info->cur_output);
712  j=main_low_apply(randr_screen_info);
713  }
714  }
715  }
716  freeScreenInfoStructure(randr_screen_info);
717  randr_screen_info = read_screen_info(randr_display);
718  for (i = 0; i < screenInfoArray.count(); i++) {
719  screendata = screenInfoArray.at(i);
720  output_info = randr_screen_info->outputs[i]->info;
721 
722  if (screendata->is_primary || screendata->is_extended) {
723  // Set rotation, refresh rate, and size
724  RandRScreen *cur_screen = new RandRScreen(i);
725  cur_screen->proposeSize(screendata->current_resolution_index);
726  cur_screen->proposeRefreshRate(screendata->current_refresh_rate_index);
727  cur_screen->proposeRotation(getHardwareRotationFlags(screendata));
728  cur_screen->applyProposed();
729  delete cur_screen;
730 
731  // Force data reload
732  randr_screen_info = read_screen_info(randr_display);
733  output_info = randr_screen_info->outputs[i]->info;
734 
735  // Finally, set the screen's position
736  randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
737  if (randr_screen_info->cur_crtc) {
738  randr_screen_info->cur_crtc->cur_x = screendata->absolute_x_position;
739  randr_screen_info->cur_crtc->cur_y = screendata->absolute_y_position;
740  j=main_low_apply(randr_screen_info);
741  }
742  }
743  }
744  freeScreenInfoStructure(randr_screen_info);
745 #endif
746  }
747 
748  applySystemwideDisplayGamma(screenInfoArray);
749  applySystemwideDisplayDPMS(screenInfoArray);
750  TQString current_icc_profile = getCurrentProfile();
751  applySystemWideIccConfiguration(kde_confdir);
752  applyIccConfiguration(current_icc_profile, kde_confdir);
753 
754  if (test == TRUE) {
755  int ret = showTestConfigurationDialog();
756  if (!ret) {
757  applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir);
758  accepted = false;
759  }
760  destroyScreenInformationObject(oldconfig);
761  }
762 
763  return accepted;
764 }
765 
766 void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
767  SingleScreenData *screendata;
768  for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) {
769  screenInfoArray.remove(screendata);
770  delete screendata;
771  }
772 }
773 
774 void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> screenInfoArray) {
775  int i;
776  SingleScreenData *screendata;
777 
778  int numberOfScreens = screenInfoArray.count();
779 
780  for (i=0;i<numberOfScreens;i++) {
781  screendata = screenInfoArray.at(i);
782  if (!screendata->screen_connected) {
783  screendata->is_primary = false;
784  screendata->is_extended = false;
785  }
786  }
787 
788  bool has_primary_monitor = false;
789  for (i=0;i<numberOfScreens;i++) {
790  screendata = screenInfoArray.at(i);
791  if (screendata->is_primary)
792  has_primary_monitor = true;
793  }
794  if (!has_primary_monitor) {
795  for (i=0;i<numberOfScreens;i++) {
796  screendata = screenInfoArray.at(i);
797  if (!has_primary_monitor) {
798  if (screendata->screen_connected && screendata->is_extended) {
799  screendata->is_primary = true;
800  screendata->is_extended = true;
801  has_primary_monitor = true;
802  }
803  }
804  }
805  }
806  if (!has_primary_monitor) {
807  for (i=0;i<numberOfScreens;i++) {
808  screendata = screenInfoArray.at(i);
809  if (!has_primary_monitor) {
810  if (screendata->screen_connected) {
811  screendata->is_primary = true;
812  screendata->is_extended = true;
813  has_primary_monitor = true;
814  }
815  }
816  }
817  }
818 
819  bool found_first_primary_monitor = false;
820  for (i=0;i<numberOfScreens;i++) {
821  screendata = screenInfoArray.at(i);
822  if (screendata->is_primary) {
823  if (!found_first_primary_monitor) {
824  found_first_primary_monitor = true;
825  }
826  else {
827  screendata->is_primary = false;
828  }
829  }
830  }
831 
832  for (i=0;i<numberOfScreens;i++) {
833  screendata = screenInfoArray.at(i);
834  if (screendata->is_primary) {
835  screendata->is_extended = true;
836  }
837  }
838 
839  for (i=0;i<numberOfScreens;i++) {
840  screendata = screenInfoArray.at(i);
841  TQString resolutionstring = screendata->resolutions[screendata->current_resolution_index];
842  int separator_pos = resolutionstring.find(" x ");
843  TQString x_res_string = resolutionstring.left(separator_pos);
844  TQString y_res_string = resolutionstring.right(resolutionstring.length()-separator_pos-3);
845  screendata->current_x_pixel_count = x_res_string.toInt();
846  screendata->current_y_pixel_count = y_res_string.toInt();
847  screendata->current_orientation_mask = getHardwareRotationFlags(screendata);
848  }
849 
850  // Each screen's absolute position is given relative to the primary monitor
851  // Fix up the absolute positions
852  int primary_offset_x = 0;
853  int primary_offset_y = 0;
854  for (i=0;i<numberOfScreens;i++) {
855  screendata = screenInfoArray.at(i);
856  if (screendata->is_primary) {
857  primary_offset_x = screendata->absolute_x_position;
858  primary_offset_y = screendata->absolute_y_position;
859  primary_offset_x = primary_offset_x * (-1);
860  primary_offset_y = primary_offset_y * (-1);
861  }
862  }
863  for (i=0;i<numberOfScreens;i++) {
864  screendata = screenInfoArray.at(i);
865  screendata->absolute_x_position = screendata->absolute_x_position + primary_offset_x;
866  screendata->absolute_y_position = screendata->absolute_y_position + primary_offset_y;
867  }
868 }
869 
870 TQPoint KRandrSimpleAPI::primaryScreenOffsetFromTLC(TQPtrList<SingleScreenData> screenInfoArray) {
871  int i;
872  SingleScreenData *screendata;
873  int numberOfScreens = screenInfoArray.count();
874 
875  int primary_offset_x = 0;
876  int primary_offset_y = 0;
877  for (i=0;i<numberOfScreens;i++) {
878  screendata = screenInfoArray.at(i);
879  if (screendata->absolute_x_position < primary_offset_x) {
880  primary_offset_x = screendata->absolute_x_position;
881  }
882  if (screendata->absolute_y_position < primary_offset_y) {
883  primary_offset_y = screendata->absolute_y_position;
884  }
885  }
886  primary_offset_x = primary_offset_x * (-1);
887  primary_offset_y = primary_offset_y * (-1);
888 
889  return TQPoint(primary_offset_x, primary_offset_y);
890 }
891 
892 void KRandrSimpleAPI::applySystemwideDisplayGamma(TQPtrList<SingleScreenData> screenInfoArray) {
893  int i;
894  Display *randr_display;
895  XRROutputInfo *output_info;
896  ScreenInfo *randr_screen_info;
897  XRRCrtcGamma *gamma;
898 
899  SingleScreenData *screendata;
900 
901  if (isValid() == true) {
902  randr_display = qt_xdisplay();
903  randr_screen_info = read_screen_info(randr_display);
904  for (i = 0; i < screenInfoArray.count(); i++) {
905  screendata = screenInfoArray.at(i);
906  output_info = randr_screen_info->outputs[i]->info;
907  CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
908  if (!current_crtc) {
909  continue;
910  }
911  // vvvvvvvvv This chunk of code is borrowed from xrandr vvvvvvvvvv
912  int size = XRRGetCrtcGammaSize(randr_display, current_crtc->id);
913  if (!size) {
914  continue;
915  }
916  gamma = XRRAllocGamma(size);
917  if (!gamma) {
918  continue;
919  }
920  for (i = 0; i < size; i++) {
921  if (screendata->gamma_red == 1.0)
922  gamma->red[i] = i << 8;
923  else
924  gamma->red[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_red) * (double)(size-1)*256);
925 
926  if (screendata->gamma_green == 1.0)
927  gamma->green[i] = i << 8;
928  else
929  gamma->green[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_green) * (double)(size-1)*256);
930 
931  if (screendata->gamma_blue == 1.0)
932  gamma->blue[i] = i << 8;
933  else
934  gamma->blue[i] = (pow((double)i/(double)(size-1), (double)screendata->gamma_blue) * (double)(size-1)*256);
935  }
936  XRRSetCrtcGamma(randr_display, current_crtc->id, gamma);
937  free(gamma);
938  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
939  }
940  freeScreenInfoStructure(randr_screen_info);
941  }
942 }
943 
944 void KRandrSimpleAPI::applySystemwideDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray) {
945  int i;
946  Display *randr_display;
947  XRROutputInfo *output_info;
948  ScreenInfo *randr_screen_info;
949  XRRCrtcGamma *gamma;
950 
951  SingleScreenData *screendata;
952 
953  if (isValid() == true) {
954  randr_display = qt_xdisplay();
955  randr_screen_info = read_screen_info(randr_display);
956  for (i = 0; i < screenInfoArray.count(); i++) {
957  screendata = screenInfoArray.at(i);
958  output_info = randr_screen_info->outputs[i]->info;
959  CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
960  if (!current_crtc) {
961  continue;
962  }
963  if (!screendata->has_dpms) {
964  continue;
965  }
966  if (screendata->enable_dpms) {
967  DPMSSetTimeouts(randr_display, screendata->dpms_standby_delay, screendata->dpms_suspend_delay, screendata->dpms_off_delay);
968  DPMSEnable(randr_display);
969  }
970  else {
971  DPMSDisable(randr_display);
972  }
973  }
974  freeScreenInfoStructure(randr_screen_info);
975  }
976 }
977 
978 void KRandrSimpleAPI::freeScreenInfoStructure(ScreenInfo* screen_info) {
979  int i;
980 
981  for (i=0; i<screen_info->n_crtc; i++) {
982  free(screen_info->crtcs[i]);
983  }
984  for (i=0; i<screen_info->n_output; i++) {
985  free(screen_info->outputs[i]);
986  }
987  free(screen_info->outputs);
988  free(screen_info->crtcs);
989  free(screen_info);
990 }
991 
992 TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
993  // Discover display information
994  int i;
995  int j;
996 
997  XRROutputInfo *output_info;
998  SingleScreenData *screendata;
999  TQPtrList<SingleScreenData> screenInfoArray;
1000 
1001  Display *randr_display;
1002  ScreenInfo *randr_screen_info;
1003 
1004  // Clear existing info
1005  destroyScreenInformationObject(screenInfoArray);
1006 
1007  int numberOfScreens = 0;
1008  if (isValid() == true) {
1009  randr_display = qt_xdisplay();
1010  randr_screen_info = read_screen_info(randr_display);
1011  for (i = 0; i < randr_screen_info->n_output; i++) {
1012  output_info = randr_screen_info->outputs[i]->info;
1013  CrtcInfo *current_crtc = randr_screen_info->outputs[i]->cur_crtc;
1014 
1015  // Create new data object
1016  screendata = new SingleScreenData;
1017  screenInfoArray.append(screendata);
1018  screendata->screenFriendlyName = TQString(i18n("%1. %2 output on %3")).arg(i+1).arg(capitalizeString(output_info->name)).arg(":0"); // [FIXME] How can I get the name of the Xorg graphics driver currently in use?
1019  screendata->generic_screen_detected = false;
1020 
1021  // Attempt to use KMS to find screen EDID and name
1022  TQString edid = getEDIDMonitorName(0, output_info->name); // [FIXME] Don't hardwire to card 0!
1023  if (!edid.isNull()) {
1024  screendata->screenFriendlyName = TQString(i18n("%1. %2 on %3 on card %4")).arg(i+1).arg(edid).arg(capitalizeString(output_info->name)).arg("0"); // [FIXME] How can I get the name of the Xorg graphics driver currently in use?
1025  }
1026 
1027  // Get resolutions
1028  bool screen_active;
1029  RandRScreen *cur_screen = 0;
1030  if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) {
1031  // Output DISCONNECTED
1032  screen_active = false;
1033  }
1034  else {
1035  if (randr_screen_info->outputs[i]->cur_crtc) {
1036  // Output CONNECTED and ON
1037  screen_active = true;
1038  cur_screen = new RandRScreen(i);
1039  }
1040  else {
1041  // Output CONNECTED and OFF
1042  screen_active = false;
1043  cur_screen = new RandRScreen(i);
1044  }
1045  }
1046 
1047  // Get DPMS information
1048  screendata->has_dpms = 1; // [FIXME] Master Xorg check for global DPMS support should go here if possible
1049  if (screendata->has_dpms) {
1050  CARD16 dpms_standby_delay;
1051  CARD16 dpms_suspend_delay;
1052  CARD16 dpms_off_delay;
1053  screendata->has_dpms = DPMSGetTimeouts(randr_display, &dpms_standby_delay, &dpms_suspend_delay, &dpms_off_delay);
1054  screendata->dpms_standby_delay = dpms_standby_delay;
1055  screendata->dpms_suspend_delay = dpms_suspend_delay;
1056  screendata->dpms_off_delay = dpms_off_delay;
1057  if (screendata->has_dpms) {
1058  CARD16 power_level;
1059  BOOL enable_dpms;
1060  screendata->has_dpms = DPMSInfo(randr_display, &power_level, &enable_dpms);
1061  screendata->enable_dpms = enable_dpms;
1062  }
1063  }
1064  if (!screendata->has_dpms) {
1065  screendata->enable_dpms = false;
1066  screendata->dpms_standby_delay = 0;
1067  screendata->dpms_suspend_delay = 0;
1068  screendata->dpms_off_delay = 0;
1069  }
1070 
1071  if (cur_screen) {
1072  screendata->screen_connected = true;
1073  for (int j = 0; j < cur_screen->numSizes(); j++) {
1074  screendata->resolutions.append(i18n("%1 x %2").arg(cur_screen->pixelSize(j).width()).arg(cur_screen->pixelSize(j).height()));
1075  }
1076  screendata->current_resolution_index = 0;
1077  if (current_crtc) {
1078  screendata->current_resolution_index = screendata->resolutions.findIndex(i18n("%1 x %2").arg(current_crtc->info->width).arg(current_crtc->info->height));
1079  }
1080  if (screendata->current_resolution_index < 0) {
1081  screendata->current_resolution_index = cur_screen->proposedSize();
1082  }
1083 
1084  // Get refresh rates
1085  TQStringList rr = cur_screen->refreshRates(screendata->current_resolution_index);
1086  for (TQStringList::Iterator it = rr.begin(); it != rr.end(); ++it) {
1087  screendata->refresh_rates.append(*it);
1088  }
1089  screendata->current_refresh_rate_index = cur_screen->proposedRefreshRate();
1090 
1091  // Get color depths
1092  // [FIXME]
1093  screendata->color_depths.append(i18n("Default"));
1094  screendata->current_color_depth_index = 0;
1095 
1096  // Get orientation flags
1097  // RandRScreen::Rotate0
1098  // RandRScreen::Rotate90
1099  // RandRScreen::Rotate180
1100  // RandRScreen::Rotate270
1101  // RandRScreen::ReflectX
1102  // RandRScreen::ReflectY
1103 
1104  screendata->rotations.append(i18n("Normal"));
1105  screendata->rotations.append(i18n("Rotate 90 degrees"));
1106  screendata->rotations.append(i18n("Rotate 180 degrees"));
1107  screendata->rotations.append(i18n("Rotate 270 degrees"));
1108  screendata->current_orientation_mask = cur_screen->proposedRotation();
1109  switch (screendata->current_orientation_mask & RandRScreen::RotateMask) {
1110  case RandRScreen::Rotate0:
1111  screendata->current_rotation_index = 0;
1112  break;
1113  case RandRScreen::Rotate90:
1114  screendata->current_rotation_index = 1;
1115  break;
1116  case RandRScreen::Rotate180:
1117  screendata->current_rotation_index = 2;
1118  break;
1119  case RandRScreen::Rotate270:
1120  screendata->current_rotation_index = 3;
1121  break;
1122  default:
1123  // Shouldn't hit this one
1124  Q_ASSERT(screendata->current_orientation_mask & RandRScreen::RotateMask);
1125  break;
1126  }
1127  screendata->has_x_flip = (screendata->current_orientation_mask & RandRScreen::ReflectX);
1128  screendata->has_y_flip = (screendata->current_orientation_mask & RandRScreen::ReflectY);
1129  screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0);
1130 
1131  // Determine if this display is primary and/or extended
1132  RROutput primaryoutput = XRRGetOutputPrimary(qt_xdisplay(), DefaultRootWindow(qt_xdisplay()));
1133  if (primaryoutput == randr_screen_info->outputs[i]->id)
1134  screendata->is_primary = false;
1135  else
1136  screendata->is_primary = true;
1137  screendata->is_extended = screen_active;
1138  if (!screendata->is_extended)
1139  screendata->is_primary = false;
1140 
1141  // Get this screen's absolute position
1142  screendata->absolute_x_position = 0;
1143  screendata->absolute_y_position = 0;
1144  if (current_crtc) {
1145  screendata->absolute_x_position = current_crtc->info->x;
1146  screendata->absolute_y_position = current_crtc->info->y;
1147  }
1148 
1149  // Get this screen's current resolution
1150  screendata->current_x_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).width();
1151  screendata->current_y_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).height();
1152 
1153  // Get this screen's current gamma values
1154  // [FIXME]
1155  // This attempts to guess a gamma value based on the LUT settings at 50%
1156  // It may not always be 100% correct, or even anywhere close...
1157  // Essentially it "undoes" the LUT gamma calculation from xrandr
1158  // lut_gamma->green[i] = (pow(i/(size - 1), desired_gamma.green) * (size - 1) * 256);
1159  screendata->gamma_red = 2.2;
1160  screendata->gamma_green = 2.2;
1161  screendata->gamma_blue = 2.2;
1162  if (current_crtc) {
1163  //int slot = 127;
1164  int slot = 7;
1165  int size = XRRGetCrtcGammaSize(randr_display, current_crtc->id);
1166  if(size>0) {
1167  XRRCrtcGamma *gammastruct = XRRGetCrtcGamma (randr_display, current_crtc->id);
1168  screendata->gamma_red = log(gammastruct->red[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
1169  screendata->gamma_green = log(gammastruct->green[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
1170  screendata->gamma_blue = log(gammastruct->blue[slot]/((size-1.0)*256.0))/log(slot/(size-1.0));
1171  }
1172  }
1173  // Round off the gamma to one decimal place
1174  screendata->gamma_red = floorf(screendata->gamma_red * 10 + 0.5) / 10;
1175  screendata->gamma_green = floorf(screendata->gamma_green * 10 + 0.5) / 10;
1176  screendata->gamma_blue = floorf(screendata->gamma_blue * 10 + 0.5) / 10;
1177 
1178  delete cur_screen;
1179  }
1180  else {
1181  // Fill in generic data for this disconnected output
1182  screendata->screenFriendlyName = screendata->screenFriendlyName + TQString(" (") + i18n("disconnected") + TQString(")");
1183  screendata->screen_connected = false;
1184 
1185  screendata->resolutions = i18n("Default");
1186  screendata->refresh_rates = i18n("Default");
1187  screendata->color_depths = i18n("Default");
1188  screendata->rotations = i18n("N/A");
1189 
1190  screendata->current_resolution_index = 0;
1191  screendata->current_refresh_rate_index = 0;
1192  screendata->current_color_depth_index = 0;
1193 
1194  screendata->gamma_red = 2.2;
1195  screendata->gamma_green = 2.2;
1196  screendata->gamma_blue = 2.2;
1197 
1198  screendata->current_rotation_index = 0;
1199  screendata->current_orientation_mask = 0;
1200  screendata->has_x_flip = false;
1201  screendata->has_y_flip = false;
1202  screendata->supports_transformations = false;
1203 
1204  screendata->is_primary = false;
1205  screendata->is_extended = false;
1206  screendata->absolute_x_position = 0;
1207  screendata->absolute_y_position = 0;
1208  screendata->current_x_pixel_count = 640;
1209  screendata->current_y_pixel_count = 480;
1210  }
1211 
1212  // Check for more screens...
1213  numberOfScreens++;
1214  }
1215 
1216  freeScreenInfoStructure(randr_screen_info);
1217  }
1218  else {
1219  screendata = new SingleScreenData;
1220  screenInfoArray.append(screendata);
1221 
1222  // Fill in a bunch of generic data
1223  screendata->screenFriendlyName = i18n("Default output on generic video card");
1224  screendata->generic_screen_detected = true;
1225  screendata->screen_connected = true;
1226 
1227  screendata->resolutions = i18n("Default");
1228  screendata->refresh_rates = i18n("Default");
1229  screendata->color_depths = i18n("Default");
1230  screendata->rotations = i18n("N/A");
1231 
1232  screendata->current_resolution_index = 0;
1233  screendata->current_refresh_rate_index = 0;
1234  screendata->current_color_depth_index = 0;
1235 
1236  screendata->gamma_red = 2.2;
1237  screendata->gamma_green = 2.2;
1238  screendata->gamma_blue = 2.2;
1239 
1240  screendata->current_rotation_index = 0;
1241  screendata->current_orientation_mask = 0;
1242  screendata->has_x_flip = false;
1243  screendata->has_y_flip = false;
1244  screendata->supports_transformations = false;
1245 
1246  screendata->is_primary = true;
1247  screendata->is_extended = true;
1248  screendata->absolute_x_position = 0;
1249  screendata->absolute_y_position = 0;
1250  screendata->current_x_pixel_count = 640;
1251  screendata->current_y_pixel_count = 480;
1252 
1253  numberOfScreens++;
1254  }
1255 
1256  // [FIXME]
1257  // Set this on the real primary monitor only!
1258  screendata = screenInfoArray.at(0);
1259  screendata->is_primary = true;
1260 
1261  return screenInfoArray;
1262 }
1263 
1264 TQString KRandrSimpleAPI::clearIccConfiguration() {
1265  // Clear ICC settings with XCalib
1266  TQString icc_command;
1267  FILE *pipe_xcalib;
1268  char xcalib_result[2048];
1269  int i;
1270  xcalib_result[0]=0;
1271 
1272  icc_command = TQString("xcalib -c");
1273  if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
1274  {
1275  printf("Xcalib pipe error [xcalib clear]\n");
1276  }
1277  else {
1278  fgets(xcalib_result, 2048, pipe_xcalib);
1279  pclose(pipe_xcalib);
1280  for (i=1;i<2048;i++) {
1281  if (xcalib_result[i] == 0) {
1282  xcalib_result[i-1]=0;
1283  i=2048;
1284  }
1285  }
1286  if (strlen(xcalib_result) > 2) {
1287  return xcalib_result;
1288  }
1289  }
1290  return "";
1291 }
1292 
1293 ScreenInfo* KRandrSimpleAPI::read_screen_info (Display *display)
1294 {
1295  return internal_read_screen_info(display);
1296 }
1297 
1298 int KRandrSimpleAPI::set_screen_size (ScreenInfo *screen_info)
1299 {
1300  return internal_set_screen_size(screen_info);
1301 }
1302 
1303 void KRandrSimpleAPI::output_auto (ScreenInfo *screen_info, OutputInfo *output_info)
1304 {
1305  internal_output_auto (screen_info, output_info);
1306 }
1307 
1308 void KRandrSimpleAPI::output_off(ScreenInfo *screen_info, OutputInfo *output)
1309 {
1310  internal_output_off(screen_info, output);
1311 }
1312 
1313 CrtcInfo* KRandrSimpleAPI::auto_find_crtc (ScreenInfo *screen_info, OutputInfo *output_info)
1314 {
1315  return internal_auto_find_crtc (screen_info, output_info);
1316 }
1317 
1318 XRRModeInfo *KRandrSimpleAPI::find_mode_by_xid (ScreenInfo *screen_info, RRMode mode_id)
1319 {
1320  return internal_find_mode_by_xid (screen_info, mode_id);
1321 }
1322 
1323 int KRandrSimpleAPI::mode_height (XRRModeInfo *mode_info, Rotation rotation)
1324 {
1325  return internal_mode_height (mode_info, rotation);
1326 }
1327 
1328 int KRandrSimpleAPI::mode_width (XRRModeInfo *mode_info, Rotation rotation)
1329 {
1330  return internal_mode_width (mode_info, rotation);
1331 }
1332 
1333 int KRandrSimpleAPI::get_width_by_output_id (ScreenInfo *screen_info, RROutput output_id)
1334 {
1335  return internal_get_width_by_output_id (screen_info, output_id);
1336 }
1337 
1338 int KRandrSimpleAPI::get_height_by_output_id (ScreenInfo *screen_info, RROutput output_id)
1339 {
1340  return internal_get_height_by_output_id (screen_info, output_id);
1341 }
1342 
1343 char *KRandrSimpleAPI::get_output_name (ScreenInfo *screen_info, RROutput id)
1344 {
1345  return internal_get_output_name (screen_info, id);
1346 }
1347 
1348 Status KRandrSimpleAPI::crtc_apply (CrtcInfo *crtc_info)
1349 {
1350  return internal_crtc_apply (crtc_info);
1351 }
1352 
1353 Status KRandrSimpleAPI::crtc_disable (CrtcInfo *crtc)
1354 {
1355  return internal_crtc_disable (crtc);
1356 }
1357 
1358 int KRandrSimpleAPI::main_low_apply (ScreenInfo *screen_info)
1359 {
1360  return internal_main_low_apply (screen_info);
1361 }
1362 
1363 bool KRandrSimpleAPI::kRandrHasRandr(void)
1364 {
1365  return isValid();
1366 }
1367 
1368 const char *KRandrSimpleAPI::kRandrVersion(void)
1369 {
1370  return "0.9.5";
1371 }
1372 
1373 const char *KRandrSimpleAPI::kRandrCopyright(void)
1374 {
1375  return "LibKRandr 0.9.5 (C)2010 Timothy Pearson <kb9vqf@pearsoncomputing.net>. U.S.A.";
1376 }
1377 
1378 /* * * * * *
1379 
1380  Under this line (------) there's only a C wrapper for the KRandrSimpleAPI class
1381 
1382 * * * * * */
1383 const char *kRandrVersion(void)
1384 {
1385  return KRandrSimpleAPI::kRandrVersion();
1386 }
1387 
1388 const char *kRandrCopyright(void)
1389 {
1390  return KRandrSimpleAPI::kRandrCopyright();
1391 }
1392 

krandr

Skip menu "krandr"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

krandr

Skip menu "krandr"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for krandr by doxygen 1.8.1.2
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |