diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/widget.cpp | 325 |
2 files changed, 218 insertions, 111 deletions
diff --git a/src/main.cpp b/src/main.cpp index 9eb8a4b..0a54d52 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,9 +8,9 @@ int main(int argc, char *argv[]) { - if (argc != 1) + if (argc != 2) { std::cout << "Usage: " << argv[0] << " <config file>" << std::endl; - else { + } else { // Check if file exists std::ifstream f(argv[1]); if (!f) { diff --git a/src/widget.cpp b/src/widget.cpp index 3386577..fd89af8 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -22,7 +22,10 @@ #define INTERFACE "eth0" #define GROUP_SPECIFIC "SpecificSettings" -//___________________________________________________________________________ +#define DEBUG + + +//_____________________________________________________________________________ Widget::Widget(QWidget *parent) : QWidget(parent), _ui(new Ui::Widget) @@ -32,7 +35,8 @@ Widget::Widget(QWidget *parent) : // Get initial data (to be freed) _display = XOpenDisplay(NULL); - _screenResources = XRRGetScreenResourcesCurrent(_display, DefaultRootWindow(_display)); + _screenResources = XRRGetScreenResourcesCurrent(_display, + DefaultRootWindow(_display)); // Get the information about the X elements updateScreenResources(); @@ -50,14 +54,19 @@ Widget::Widget(QWidget *parent) : // adresses cases in which eiter of the outouts is a beamer. Meaning // either output one has dimension zero or output tow has no dimension. // The case of two beamers is not covered. - if (((_outputMap[_connectedOutputList[0]]->mm_width == 0 +#ifdef DEBUG + if ( true ) { +#else + if ( ((_outputMap[_connectedOutputList[0]]->mm_width == 0 && _outputMap[_connectedOutputList[0]]->mm_height == 0 ) && ! (_outputMap[_connectedOutputList[1]]->mm_width == 0 && _outputMap[_connectedOutputList[1]]->mm_height == 0 )) || ( ! (_outputMap[_connectedOutputList[0]]->mm_width == 0 && _outputMap[_connectedOutputList[0]]->mm_height == 0 ) && (_outputMap[_connectedOutputList[1]]->mm_width == 0 - && _outputMap[_connectedOutputList[1]]->mm_height == 0 ))) { + && _outputMap[_connectedOutputList[1]]->mm_height == 0 )) ) { +#endif + qDebug() << "BEAMER CONNECTED!"; // Get a human readable reference @@ -72,6 +81,7 @@ Widget::Widget(QWidget *parent) : } // /opt/openslx/config + // // Get the ip adress of the interface // struct ifaddrs * ifAddrStruct=NULL; // struct ifaddrs * ifa=NULL; @@ -151,8 +161,6 @@ Widget::Widget(QWidget *parent) : // m2, // RR_Rotate_0, // &_beamer, 1); - - // } // settings.endGroup(); @@ -171,63 +179,92 @@ Widget::Widget(QWidget *parent) : } free(props); - // // TO BE DONE VIA BASH -// // Iterate over the modes in the config file -// for (QList<QString>::const_iterator it = -// Config::inst()->getModeLines().begin(); -// it != Config::inst()->getModeLines().end(); ++it) { -// // Add mode to xrandr -// QProcess p; -// QStringList arguments; -// arguments << "--current" << "--newmode" -// << it->split(" ", QString::SkipEmptyParts); -// p.start("xrandr", arguments); -// p.waitForFinished(); -// } + // Intersect them by the resolution sorted, dont care about O(n³) + QList<QPair<XRRModeInfo*, XRRModeInfo*> > commonModes; + // Iterate over the modes the monitor supports + for (int i = 0; i < _outputMap[_monitor]->nmode; ++i) { - // Get the names of the modes and intersect - QSet<XRRModeInfo*> beamerModes, monitorModes; - for (int i = 0; i < _outputMap[_beamer]->nmode; ++i) - beamerModes.insert(_modeMap[_outputMap[_beamer]->modes[i]]); - for (int i = 0; i < _outputMap[_monitor]->nmode; ++i) - monitorModes.insert(_modeMap[_outputMap[_monitor]->modes[i]]); - - // Intersect them by the resolution sorted - // dont care about O(n³) - QList<XRRModeInfo*> commonModes; - for (QSet<XRRModeInfo*>::iterator i = beamerModes.begin(); - i != beamerModes.end(); ++i) { - if ((*i)->modeFlags & RR_Interlace) continue; - for (QSet<XRRModeInfo*>::iterator j = monitorModes.begin(); - j != monitorModes.end(); ++j) { - if ((*j)->modeFlags & RR_Interlace) continue; - QList<XRRModeInfo*>::iterator k = commonModes.begin(); - for (;;) { - if (k == commonModes.end()){ - commonModes.insert(k, *i); - break; - } - if ( (*i)->width == (*k)->width ) { - if ( (*i)->height == (*k)->height ) + XRRModeInfo* monitorMode = _modeMap[_outputMap[_monitor]->modes[i]]; + + // Skip interlaces modes + if ( monitorMode->modeFlags & RR_Interlace ) + continue; + + // Iterate over the modes the beamer supports + for (int j = 0; j < _outputMap[_beamer]->nmode; ++j) { + + XRRModeInfo* beamerMode = _modeMap[_outputMap[_beamer]->modes[j]]; + + // Skip interlaces modes + if ( beamerMode->modeFlags & RR_Interlace ) + continue; + + // Only if the modes have the same size, list them in common modes + if ( monitorMode->height == beamerMode->height + && monitorMode->width == beamerMode->width ) { + +// qDebug() << "Potential common mode" +// << monitorMode->width +// << monitorMode->height ; + + // Build a sorted list of common modes in descending order + QList<QPair<XRRModeInfo*, XRRModeInfo*> >::iterator k = commonModes.begin(); + for (;;++k) { + + // If at the end, the mode to insert is the smallest, insert. + // This has to be first to avoid segfaults + if (k == commonModes.end()) { + + commonModes.insert(k, qMakePair (monitorMode, beamerMode)); +// qDebug() << "Smallest" +// << monitorMode->width +// << monitorMode->height ; break; - if ( (*i)->height > (*k)->height ) { - commonModes.insert(k, *i); + } + + // If the mode to insert is larger than k, insert. + if ( monitorMode->width > k->first->width) { + commonModes.insert(k, qMakePair (monitorMode, beamerMode)); +// qDebug() << "Insert" +// << monitorMode->width +// << monitorMode->height ; break; } + + // If the width is the same ... + if ( monitorMode->width == k->first->width ) { + + // ... and the height is the same, the mode already exists + if ( monitorMode->height == k->first->height ) { +// qDebug() << "Already exists" +// << monitorMode->width +// << monitorMode->height ; + break; + } + + // ... and the height is larger, insert. + if ( monitorMode->height > k->first->height ) { + commonModes.insert(k, qMakePair (monitorMode, beamerMode)); +// qDebug() << "Insert" +// << monitorMode->width +// << monitorMode->height ; + break; + } + } } - if ( (*i)->width > (*k)->width ) { - commonModes.insert(k, *i); - break; - } - ++k; } } } // If the beamer transmits no reliable EDID data add modes +#ifdef DEBUG + gotEDID = false; +#endif if (gotEDID) { - std::cout << "GOT EDID!" << std::endl; + + qDebug() << "GOT EDID!"; + // Extract the preferred mode of the beamer RRMode preferredBeamerModeId; for (int i = 0; i < _outputMap[_beamer]->nmode; ++i) { @@ -242,39 +279,29 @@ Widget::Widget(QWidget *parent) : / _modeMap[preferredBeamerModeId]->height; // Fill widget with data - for ( QList<XRRModeInfo*>::iterator i = commonModes.begin(); + for ( QList<QPair<XRRModeInfo*, XRRModeInfo*> >::iterator i = commonModes.begin(); i != commonModes.end(); ++i ) { - float modeAspectRatio = ((float)(*i)->width / (*i)->height); + float modeAspectRatio = ((float)i->first->width / i->first->height); if ( modeAspectRatio == aspectRatio ) // TODO APPROX - _ui->comboBox->addItem((*i)->name); + _ui->comboBox->addItem(i->first->name, + QList<QVariant>() + << QVariant((qulonglong)i->first->id) + << QVariant((qulonglong)i->second->id)); } - -// // TO BE DONE VIA BASH -// // Iterate over all modes and add them to the outputs, -// // if the AR matches. -// for(ModeMap::iterator it = _modeMap.begin(); -// it != _modeMap.end(); ++it) { -// float MODEAR = ((float)(*it)->width / (*it)->height); -// if ( MODEAR == AR ) { -// XRRAddOutputMode(_display, _beamer, (*it)->id); -// XRRAddOutputMode(_display, _monitor, (*it)->id); -// } -// } } else { + qDebug() << "NO EDID!"; + // Fill widget with data without AR match // Fill widget with data - for ( QList<XRRModeInfo*>::iterator i = commonModes.begin(); + for ( QList<QPair<XRRModeInfo*, XRRModeInfo*> >::iterator i = commonModes.begin(); i != commonModes.end(); ++i ) { - _ui->comboBox->addItem((*i)->name); + qDebug() << "Combo insert" << i->first->width << "x" << i->first->height ; + _ui->comboBox->addItem(i->first->name, + QList<QVariant>() + << QVariant((qulonglong)i->first->id) + << QVariant((qulonglong)i->second->id)); } - // TO BE DONE VIA BASH -// // Iterate over all modes and add them to the outputs -// for(ModeMap::iterator it = _modeMap.begin(); -// it != _modeMap.end(); ++it) { -// XRRAddOutputMode(_display, _beamer, (*it)->id); -// XRRAddOutputMode(_display, _monitor, (*it)->id); -// } } // Remove borders and stuff @@ -380,7 +407,7 @@ Widget::~Widget() void Widget::handleButton() { // Backup the crtcinfos - qDebug() << "// Backup the crtcinfos"; + qDebug() << "Backup the crtc infos"; CrtcMap backup; for ( CrtcMap::iterator it = _crtcMap.begin(); it != _crtcMap.end(); ++it ) { @@ -396,32 +423,16 @@ void Widget::handleButton() } } - // First get a useful representation - qDebug() << "// First get a useful representation"; - unsigned int width, height; - QStringList modeAsStrings = _ui->comboBox->currentText().split("x", QString::SkipEmptyParts); - width = modeAsStrings.at(0).toInt(); - height = modeAsStrings.at(1).toInt(); - - // Find a mode that matches the string - RRMode m1,m2; - qDebug() << "// Find a mode that matches the string"; - for (int i = 0; i < _outputMap[_monitor]->nmode; ++i){ - if ( width == _modeMap[_outputMap[_monitor]->modes[i]]->width - && height == _modeMap[_outputMap[_monitor]->modes[i]]->height - && !(_modeMap[_outputMap[_monitor]->modes[i]]->modeFlags & RR_Interlace) ) // skip interlaced modes - m1 = _modeMap[_outputMap[_monitor]->modes[i]]->id; - } - qDebug() << "// Find a mode that matches the string"; - for (int i = 0; i < _outputMap[_beamer]->nmode; ++i){ - if ( width == _modeMap[_outputMap[_beamer]->modes[i]]->width - && height == _modeMap[_outputMap[_beamer]->modes[i]]->height - && !(_modeMap[_outputMap[_beamer]->modes[i]]->modeFlags & RR_Interlace) ) // skip interlaced modes - m2 = _modeMap[_outputMap[_beamer]->modes[i]]->id; - } + // Get the modes from QComboBox + QList<QVariant> modes = _ui->comboBox->itemData( _ui->comboBox->currentIndex()).toList(); + XRRModeInfo* monitorMode = _modeMap[modes[0].toULongLong()]; + XRRModeInfo* beamerMode = _modeMap[modes[1].toULongLong()]; // Set screensize - qDebug() << "// Set screensize"; + uint width = monitorMode->width; + uint height = monitorMode->height; + + qDebug() << " Set screensize to" << width << height; XRRSetScreenSize(_display, DefaultRootWindow(_display), width, height, @@ -429,37 +440,33 @@ void Widget::handleButton() 25.4 * height / 96); // standard dpi that X uses // Apply the modes - qDebug() << "// Apply the modes"; + qDebug() << "Apply the modes" << monitorMode->id << beamerMode->id; XRRSetCrtcConfig(_display, _screenResources, _outputMap[_monitor]->crtc, CurrentTime, - 0, 0, m1, + 0, 0, monitorMode->id, RR_Rotate_0, &_monitor, 1); XRRSetCrtcConfig(_display, _screenResources, _outputMap[_beamer]->crtc, CurrentTime, - 0, 0, m2, + 0, 0, beamerMode->id, RR_Rotate_0, &_beamer, 1); // Center widget on screenbottom - qDebug() << "// Center widget on screenbottom"; + qDebug() << "Center widget on screenbottom"; this->move( width/2 - this->width()/2, height - this->height()); // Show a dialog asking if the res should be kept - qDebug() << "// Show a dialog asking if the res should be kept"; + qDebug() << "Show a dialog asking if the res should be kept"; TimeOutDialog *keepDialog = new TimeOutDialog(15, this); keepDialog->setWindowTitle(" "); keepDialog->setLabelText("Do you want to keep this resolution?"); keepDialog->setCancelButtonText("Keep"); - - // Center the dialog - qDebug() << "// Center the dialog"; keepDialog->move( width/2 - this->width()/2, height/2 - this->height()); - keepDialog->exec(); // If the dialog was not canceled revert the resolution @@ -485,9 +492,13 @@ void Widget::handleButton() QSize ScreenSize(0,0); for ( CrtcMap::iterator it = backup.begin(); it != backup.end(); ++it ) { + + qDebug() << "// Then calc backed up screensize"; + ScreenSize.setWidth( std::max((uint)ScreenSize.width(), it.value()->x+_modeMap[it.value()->mode]->width)); + ScreenSize.setHeight( std::max((uint)ScreenSize.height(), it.value()->y+_modeMap[it.value()->mode]->height)); @@ -551,3 +562,99 @@ void Widget::handleButton() // << "--same-as" <<_outputMap[_monitor]->name; // p.start("xrandr", arguments); // p.waitForFinished(); + +// // TO BE DONE VIA BASH +// // Iterate over the modes in the config file +// for (QList<QString>::const_iterator it = +// Config::inst()->getModeLines().begin(); +// it != Config::inst()->getModeLines().end(); ++it) { +// // Add mode to xrandr +// QProcess p; +// QStringList arguments; +// arguments << "--current" << "--newmode" +// << it->split(" ", QString::SkipEmptyParts); +// p.start("xrandr", arguments); +// p.waitForFinished(); +// } + +// // TO BE DONE VIA BASH +// // Iterate over all modes and add them to the outputs, +// // if the AR matches. +// for(ModeMap::iterator it = _modeMap.begin(); +// it != _modeMap.end(); ++it) { +// float MODEAR = ((float)(*it)->width / (*it)->height); +// if ( MODEAR == AR ) { +// XRRAddOutputMode(_display, _beamer, (*it)->id); +// XRRAddOutputMode(_display, _monitor, (*it)->id); +// } +// } + +// TO BE DONE VIA BASH +// // Iterate over all modes and add them to the outputs +// for(ModeMap::iterator it = _modeMap.begin(); +// it != _modeMap.end(); ++it) { +// XRRAddOutputMode(_display, _beamer, (*it)->id); +// XRRAddOutputMode(_display, _monitor, (*it)->id); + +// // Get the names of the modes and intersect +// QSet<XRRModeInfo*> beamerModes, monitorModes; +// for (int i = 0; i < _outputMap[_beamer]->nmode; ++i) +// beamerModes.insert(_modeMap[_outputMap[_beamer]->modes[i]]); +// for (int i = 0; i < _outputMap[_monitor]->nmode; ++i) +// monitorModes.insert(_modeMap[_outputMap[_monitor]->modes[i]]); + +// // Intersect them by the resolution sorted +// // dont care about O(n³) +// QList<XRRModeInfo*> commonModes; +// for (QSet<XRRModeInfo*>::iterator i = beamerModes.begin(); +// i != beamerModes.end(); ++i) { +// if ((*i)->modeFlags & RR_Interlace) continue; +// for (QSet<XRRModeInfo*>::iterator j = monitorModes.begin(); +// j != monitorModes.end(); ++j) { +// if ((*j)->modeFlags & RR_Interlace) continue; +// QList<XRRModeInfo*>::iterator k = commonModes.begin(); +// for (;;) { +// if (k == commonModes.end()){ +// commonModes.insert(k, *i); +// break; +// } +// if ( (*i)->width == (*k)->width ) { +// if ( (*i)->height == (*k)->height ) +// break; +// if ( (*i)->height > (*k)->height ) { +// commonModes.insert(k, *i); +// break; +// } +// } +// if ( (*i)->width > (*k)->width ) { +// commonModes.insert(k, *i); +// break; +// } +// ++k; +// } +// } +// }// } + +// // First get a useful representation +// qDebug() << "// First get a useful representation"; +// unsigned int width, height; +// QStringList modeAsStrings = +// _ui->comboBox->currentText().split("x", QString::SkipEmptyParts); +// width = modeAsStrings.at(0).toInt(); +// height = modeAsStrings.at(1).toInt(); +// // Find a mode that matches the string +// RRMode m1,m2; +// qDebug() << "// Find a mode that matches the string"; +// for (int i = 0; i < _outputMap[_monitor]->nmode; ++i){ +// if ( width == _modeMap[_outputMap[_monitor]->modes[i]]->width +// && height == _modeMap[_outputMap[_monitor]->modes[i]]->height +// && !(_modeMap[_outputMap[_monitor]->modes[i]]->modeFlags & RR_Interlace) ) // skip interlaced modes +// m1 = _modeMap[_outputMap[_monitor]->modes[i]]->id; +// } +// qDebug() << "// Find a mode that matches the string"; +// for (int i = 0; i < _outputMap[_beamer]->nmode; ++i){ +// if ( width == _modeMap[_outputMap[_beamer]->modes[i]]->width +// && height == _modeMap[_outputMap[_beamer]->modes[i]]->height +// && !(_modeMap[_outputMap[_beamer]->modes[i]]->modeFlags & RR_Interlace) ) // skip interlaced modes +// m2 = _modeMap[_outputMap[_beamer]->modes[i]]->id; +// } |