From 21aa80032f685b3ded10fe293ca083d2f46ae18c Mon Sep 17 00:00:00 2001 From: Manuel Schneider Date: Thu, 21 Nov 2013 15:38:19 +0100 Subject: alpha --- src/x.cpp | 473 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 473 insertions(+) create mode 100644 src/x.cpp (limited to 'src/x.cpp') diff --git a/src/x.cpp b/src/x.cpp new file mode 100644 index 0000000..6c9e0e2 --- /dev/null +++ b/src/x.cpp @@ -0,0 +1,473 @@ +#include "x.h" +#include +namespace X +{ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + Screen * Screen::_instance = NULL; + + Screen::Screen() + { + // Get initial data (to be freed) + _display = XOpenDisplay(NULL); + _screenResources = XRRGetScreenResourcesCurrent(_display, DefaultRootWindow(_display)); + + /* Get informations about Xserver */ + + // Create the modemap + for (int i = 0; i < _screenResources->nmode; ++i) + { + _modeMap.insert( + _screenResources->modes[i].id, + Mode(&_screenResources->modes[i]) + ); + } + + // Create crtcMap + for (int i = 0; i < _screenResources->ncrtc; ++i) + { + _crtcMap.insert( + _screenResources->crtcs[i], + Crtc(_screenResources->crtcs[i],this) + ); + } + + // Create outputMap + for (int i = 0; i < _screenResources->noutput; ++i) + { + _outputMap.insert( + _screenResources->outputs[i], + new Output(_screenResources->outputs[i], this) + ); + } + + // Create connectedOutputMap + for (OutputMap::iterator it = _outputMap.begin(); + it != _outputMap.end(); ++it) + if ( (*it)->isConnected() ) + _connectedOutputList.push_back((*it)->_id); + + } + + //___________________________________________________________________________ + Screen::~Screen() + { + XCloseDisplay(_display); + XRRFreeScreenResources(_screenResources); + for (int i = 0; i < _outputMap.size(); ++i) + delete _outputMap[i]; + } + + +// //_________________________________________________________________________ +//// int Screen::applyChanges() +//// { +//// // First make backup to restore in case of an error or user interaction + +//// // Calculate screensize +//// QRect screenSize; +//// for (CrtcMap::iterator i = _crtcMap.begin(); i != _crtcMap.end(); ++i) +//// screenSize = screenSize.united(i->getRect()); + +//// /* values from xrandr */ +//// float dpi = (25.4 * DisplayHeight(_display, 0)) / +//// DisplayHeightMM(_display, 0); +//// int widthMM = (int) ((25.4 * screenSize.width()) / dpi); +//// int heightMM = (int) ((25.4 * screenSize.height()) / dpi); + +//// // Set screensize +//// XRRSetScreenSize(_display, DefaultRootWindow(_display), +//// screenSize.width(), +//// screenSize.height(), +//// widthMM, heightMM); + +//// // Apply changes of each crtc +//// // Stupid applying here, sanitychecks have to be done before +//// for (CrtcMap::iterator i = _crtcMap.begin(); i != _crtcMap.end(); ++i) +//// { +//// if ( i->applyChanges() ) +//// { +//// revertChanges(); +//// return EXIT_FAILURE; +//// } +//// } +//// return EXIT_SUCCESS; +//// } + + +//// //_________________________________________________________________________ +//// void Screen::revertChanges() +//// { +//// // TODO +//// } + +//// OutputList Screen::getConnectedOutputs() const +//// { +//// OutputList result; +//// for (OutputMap::const_iterator it = _outputMap.begin(); +//// it != _outputMap.end(); ++it) +//// if (it->isConnected()) +//// result.push_back(it->_id); +//// return result; +//// } + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + XElement::XElement(XID xid) + : _id(xid), _validity(false) {} + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + Mode::Mode(XRRModeInfo *info) + { + if ( info == NULL ) + return; + _id = info->id; + _dotClock = info->dotClock; + _hSyncStart = info->hSyncStart; + _hSyncEnd = info->hSyncEnd; + _hTotal = info->hTotal; + _hSkew = info->hSkew; + _vSyncStart = info->vSyncStart; + _vSyncEnd = info->vSyncEnd; + _vTotal = info->vTotal; + _name = QString(info->name); + _modeFlags = info->modeFlags; + _resolution.setWidth(info->width); + _resolution.setHeight(info->height); + _validity = true; + // rate = ((float) info->dotClock / ((float) info->hTotal * (float) info->vTotal)); + + qDebug() << "Mode: " << _id << _resolution.width() << _resolution.height(); + } + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + Crtc::Crtc(XID id = None, Screen * parent = NULL) + : XElement(id), _parent(parent) + { + // Get the information from XRROutputInfo + XRRCrtcInfo * info = XRRGetCrtcInfo( + const_cast(_parent->display()), + const_cast(_parent->screenResources()), + id); + + // Leave invalid if XID not existent + if ( !info ){ + return; + } + + _timestamp = info->timestamp; + _crtcRect = QRect( + info->x, + info->y, + info->width, + info->height); + _mode = info->mode; + + for (int i = 0; i < info->noutput; ++i) + _outputs.append(info->outputs[i]); + + for (int i = 0; i < info->npossible; ++i) + _possible.append(info->possible[i]); + + _rotation = info->rotation; + _rotations = info->rotations; + _validity = true; + XRRFreeCrtcInfo(info); + + qDebug() << "Crtc: " << _id << _mode << _outputs + << _crtcRect; + } + +//// int Crtc::applyChanges() +//// { +//// return XRRSetCrtcConfig(_parent->display, +//// _parent->screenResources, +//// _id, +//// _timestamp, +//// _crtcRect.x(), +//// _crtcRect.y(), +//// _mode, +//// _rotation, +//// _outputs.toVector().data(), +//// _outputs.size() +//// ); +//// } + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + Output::Output(XID id, Screen * parent) + : XElement(id), _parent(parent), _hasReliableEDID(false) + { + // Get the information from XRROutputInfo + XRROutputInfo* info = XRRGetOutputInfo( + const_cast(_parent->display()), + const_cast(_parent->screenResources()), + id); + + // Leave invalid if XID not existent + if ( !info ){ + return; + } + + _timestamp = info->timestamp; + _crtc = info->crtc; + _name = QString(info->name); + _metricDimension.setWidth(info->mm_width); + _metricDimension.setHeight(info->mm_height); + _connection = (State)info->connection; + //subpixel_order = info->subpixel_order; + for (int i = 0; i < info->ncrtc; ++i) + _crtcs.append(info->crtcs[i]); + for (int i = 0; i < info->nclone; ++i) + _clones.append(info->clones[i]); + + // List the supported modes and extract preferred + // This is the point where creating the modemap before the outputmap + // gets a contition. + for (int i = 0; i < info->nmode; ++i){ + _modes.insert(info->modes[i]); + if (i < info->npreferred) + _preferred = i; + } + XRRFreeOutputInfo(info); + + // Check if this is a beamer + _isProjector = _metricDimension.isEmpty(); + + // Maybe obsolete, since no preferred mode means no EDID. + // // EDID = ?; + int nprop; + Atom *props = XRRListOutputProperties( + const_cast(_parent->display()), + _id, + &nprop); + + for (int i = 0; i < nprop; ++i) + { + char *atom_name = XGetAtomName ( + const_cast(_parent->display()), + props[i]); + if ( strcmp (atom_name, "EDID") == 0) + { +// // Print Stuff +// unsigned long nitems, bytes_after; +// unsigned char *prop; +// int actual_format; +// Atom actual_type; +// int bytes_per_item; + +// XRRGetOutputProperty (dpy, ID, props[i], +// 0, 100, False, False, +// AnyPropertyType, +// &actual_type, &actual_format, +// &nitems, &bytes_after, &prop); + +// XRRPropertyInfo *propinfo = XRRQueryOutputProperty(dpy, ID, props[i]); +// bytes_per_item = actual_format / 8; + +// fprintf (stderr, "\t%s: ", atom_name); +// for (unsigned int k = 0; k < nitems; k++) +// { +// if (k != 0) +// { +// if ((k % 16) == 0) +// { +// fprintf (stderr, "\n\t\t"); +// } +// } +// const uint8_t *val = prop + (k * bytes_per_item); +// fprintf (stderr, "%d02", *val); +// } +// free(propinfo); + _hasReliableEDID = true; + } + } + free(props); + + + qDebug() << "Output: " << _id << _name << _crtc + << _metricDimension << _clones << _modes; + } + +// //_________________________________________________________________________ +//// int Screen::Output::changeMode(XID mode) +//// { +//// // Check if this mode is supported +//// if ( ! _modes.contains(mode) ) +//// return 1; + +//// // Check if this output is connected +//// if ( _connection != Output::Connected ) +//// return 2; + +//// // If this output is NOT conected to a crtc +//// if ( ! isActive() ) +//// { +//// // Try to find a unconnected crtc which +//// // this output can be connected to +//// for (CrtcList::iterator i = _crtcs.begin(); ; ++i) +//// { +//// // If this search reches end no appropriate +//// // crtc has been found +//// if ( i == _crtcs.end() ) +//// return 3; + +//// // If a free crtc was found connect and apply mode +//// if ( _parent->_crtcMap[*i].getConnectedOutputs().empty() ) +//// { +//// _parent->_crtcMap[*i].connect(this, mode); +//// break; +//// } +//// } +//// } +//// //If it is already connected apply mode to the crtc +//// // TODO(Manuel):continue +//// return 0; +//// } + +//// //_________________________________________________________________________ +//// int Output::changePos() +//// { +//// return 1; +//// } +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +} + + + + + + + + + + + + + + + + + + + + + + + +//// qDebug() << XRRSetCrtcConfig(display, +//// screenResources, +//// screenResources->crtcs[1], +//// CurrentTime, +//// 0, 0, +//// 597, +//// RR_Rotate_0, +//// &(screenResources->outputs[3]), +//// 1); +//// qDebug() << XRRSetCrtcConfig(display, +//// screenResources, +//// screenResources->crtcs[0], +//// CurrentTime, +//// 1920, 0, +//// 586, +//// RR_Rotate_0, +//// &(screenResources->outputs[1]), +//// 1); +//// HOLY!! +//// XRRSetCrtcConfig(display, +//// screenResources, +//// screenResources->crtcs[1], +//// CurrentTime, +//// 0, 0, +//// 587, +//// RR_Rotate_0, +//// &screenResources->outputs[1], +//// 1); + + + + + + + + + +/////////////////////////////// DBEUG //// DEBUG ////////////////////////////////// +//// //SCREEN +//// qDebug() << "ScreenResources: "; +//// qDebug() << "Count of crtcs: " << screenResources->ncrtc; +//// qDebug() << "Count of outputs: " << screenResources->noutput; +//// qDebug() << "Count of modes: " << screenResources->nmode; + +//// //MODES +//// for (int i = 0; i < screenResources->nmode; ++i) +//// { +//// qDebug() << screenResources->modes[i].id +//// << screenResources->modes[i].width +//// << screenResources->modes[i].height +////// << screenResources->modes[i].dotClock +////// << screenResources->modes[i].hSyncStart +////// << screenResources->modes[i].hSyncEnd +////// << screenResources->modes[i].hTotal +////// << screenResources->modes[i].hSkew +////// << screenResources->modes[i].vSyncStart +////// << screenResources->modes[i].vSyncEnd +////// << screenResources->modes[i].vTotal +////// << screenResources->modes[i].nameLength +//// << screenResources->modes[i].name; +//// } + +//// //CRTCS +//// for (int j = 0; j < screenResources->ncrtc; ++j) +//// { +//// XRRCrtcInfo *CrtcInfo = XRRGetCrtcInfo(display, screenResources, screenResources->crtcs[j]); +//// qDebug() << "\n-------- CrtcInfo"; +//// qDebug() << "timestamp: " << CrtcInfo->timestamp; +//// qDebug() << "x: " << CrtcInfo->x; +//// qDebug() << "y: " << CrtcInfo->y; +//// qDebug() << "width: " << CrtcInfo->width; +//// qDebug() << "height: " << CrtcInfo->height; +//// qDebug() << "rotation: " << CrtcInfo->rotation; +//// qDebug() << "noutput: " << CrtcInfo->noutput; +//// qDebug() << "rotations: " << CrtcInfo->rotations; +//// qDebug() << "npossible: " << CrtcInfo->npossible; +//// XRRFreeCrtcInfo(CrtcInfo); +//// } + +//// // OUTPUTS +//// for (int nOut = 0; nOut < screenResources->noutput; ++nOut) +//// { +//// XRROutputInfo *OutputInfo = XRRGetOutputInfo (display, screenResources, screenResources->outputs[nOut]); +////// if (OutputInfo->connection == RR_Connected) { +//// qDebug() << "\n--- Output " << nOut; +//// qDebug() << "name " << OutputInfo->name; +//// qDebug() << "mm_width " << OutputInfo->mm_width; +//// qDebug() << "mm_height " << OutputInfo->mm_height; +//// qDebug() << "ncrtc " << OutputInfo->ncrtc; +//// qDebug() << "nclone " << OutputInfo->nclone; +//// qDebug() << "nmode " << OutputInfo->nmode; +//// qDebug() << "npreferred " << OutputInfo->npreferred; + +//// for (int j = 0; j < OutputInfo->nmode; j++) +//// { +//// qDebug() << "mode" << j << ": " << OutputInfo->modes[j]; +//// } +////// } +//// XRRFreeOutputInfo (OutputInfo); +//// } +/////////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3-55-g7522