summaryrefslogtreecommitdiffstats
path: root/src/x.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/x.cpp')
-rw-r--r--src/x.cpp473
1 files changed, 473 insertions, 0 deletions
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 <QDebug>
+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<Display*>(_parent->display()),
+ const_cast<XRRScreenResources*>(_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<Display*>(_parent->display()),
+ const_cast<XRRScreenResources*>(_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<Display*>(_parent->display()),
+ _id,
+ &nprop);
+
+ for (int i = 0; i < nprop; ++i)
+ {
+ char *atom_name = XGetAtomName (
+ const_cast<Display*>(_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);
+//// }
+///////////////////////////////////////////////////////////////////////////////////