#ifndef XRANDR_H
#define XRANDR_H
#include <QDebug>
#include <QList>
#include <QMap>
#include <QString>
#include <QRect>
#include <QSet>
#include <QSize>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
namespace X
{
class Mode;
class Output;
class Crtc;
typedef QSet<RRMode> ModeSet;
typedef QSet<RRCrtc> CrtcSet;
typedef QSet<RROutput> OutputSet;
typedef QList<RRMode> ModeList;
typedef QList<RRCrtc> CrtcList;
typedef QList<RROutput> OutputList;
///////////////////////////////////////////////////////////////////////////
class Screen
{
friend class Crtc;
friend class Output;
public:
typedef QMap<RRMode,Mode> ModeMap;
typedef QMap<RRCrtc,Crtc> CrtcMap;
typedef QMap<RROutput,Output*> OutputMap;
int applyChanges();
void revertChanges();
// Getters
inline const Display* display() const {return _display;}
inline const XRRScreenResources* screenResources() const {return _screenResources;}
inline const ModeMap& getModeMap() const {return _modeMap;}
inline const OutputMap& getOutputMap() const {return _outputMap;}
inline const OutputList& getConnectedOutputList() const {return _connectedOutputList;}
// Singleton
inline static Screen* inst() {
if (_instance == 0) _instance = new Screen();
return _instance;
}
private:
Screen();
~Screen();
static Screen * _instance;
Display* _display;
XRRScreenResources* _screenResources;
ModeMap _modeMap;
CrtcMap _crtcMap;
OutputMap _outputMap;
OutputList _connectedOutputList;
};
///////////////////////////////////////////////////////////////////////////
struct XElement
{
XElement(XID = 0);
XID _id;
bool _validity;
inline XID getID() const {return _id;}
inline XID isValid() const {return _validity;}
};
///////////////////////////////////////////////////////////////////////////
struct Mode : public XElement
{
Mode(XRRModeInfo* = NULL);
// Xlib internal stuff
QSize _resolution;
unsigned long _dotClock;
unsigned int _hSyncStart;
unsigned int _hSyncEnd;
unsigned int _hTotal;
unsigned int _hSkew;
unsigned int _vSyncStart;
unsigned int _vSyncEnd;
unsigned int _vTotal;
QString _name;
XRRModeFlags _modeFlags;
};
///////////////////////////////////////////////////////////////////////////
class Output : public XElement
{
friend int Screen::applyChanges();
friend void Screen::revertChanges();
typedef enum _State {
Connected = RR_Connected,
Disconnected = RR_Disconnected,
Unknown = RR_UnknownConnection
} State;
public:
Output(XID, Screen*);
/** Public interface to modify output settings.
* This function is the only interface to the outside, which is able to
* change something in this object.
* @param active Indicates wheter the output shall be on or off.
* @param mode The mode wich is used for the output.
* @param position The position of the topleft corner on the screen.
* @return 0 if the config passed teh sanity checks.
*/
int changeConfiguration(bool active, XID mode, QPoint position);
inline QString getName() const {return _name;}
inline ModeSet getModeSet() const {return _modes;}
inline RRMode getPreferred() const {return _preferred;}
inline bool isActive() const {return !_crtcs.isEmpty();}
inline bool isConnected() const {return _connection == Connected;}
inline bool isProjector() const {return _isProjector;}
inline bool hasReliableEDID() const {return _hasReliableEDID;}
private:
Screen *_parent;
// Indicates when the configuration was last set.
Time _timestamp;
// The current source CRTC for video data, or Disabled if the
// output is not connected to any CRTC.
RRCrtc _crtc;
// UTF-8 encoded string designed to be presented to the
// user to indicate which output this is. E.g. "S-Video" or "DVI".
QString _name;
// 'widthInMillimeters' and 'heightInMillimeters' report the physical
// size of the displayed area. If unknown, or not really fixed (e.g.,
// for a projector), these values are both zero.
QSize _metricDimension;
// Indicates whether the hardware was able to detect a
// device connected to this output. If the hardware cannot determine
// whether something is connected, it will set this to
// UnknownConnection.
State _connection;
// // Contains the resulting subpixel order of the
// // connected device to allow correct subpixel rendering.
// SubpixelOrder _subpixel_order;
// The list of CRTCs that this output may be connected to.
// Attempting to connect this output to a different CRTC results in a
// Match error.
CrtcList _crtcs;
// The list of outputs which may be simultaneously
// connected to the same CRTC along with this output. Attempting to
// connect this output with an output not in this list
// results in a Match error.
OutputList _clones;
// The list of modes supported by this output. Attempting to
// connect this output to a CRTC not using one of these modes results
// in a Match error.
ModeSet _modes;
// The first 'num-preferred' modes in 'modes' are preferred by the
// monitor in some way; for fixed-pixel devices, this would generally
// indicate which modes match the resolution of the output device.
RRMode _preferred;
// Indicates wheter this is a beamer or not.
bool _isProjector;
// Indicates wheter the output received reliable data over the DDC.
// The Display Data Channel, or DDC, is a collection of protocols for
// digital communication between a computer display and a graphics
// adapter that enable the display to communicate its supported display
// modes to the adapter and that enable the computer host to adjust
// monitor parameters, such as brightness and contrast.
// Extended display identification data (EDID) is a data structure
// provided by a digital display to describe its capabilities to a
// video source.
bool _hasReliableEDID;
};
///////////////////////////////////////////////////////////////////////////
class Crtc : public XElement
{
friend int Screen::applyChanges();
friend void Screen::revertChanges();
friend int Output::changeConfiguration(bool active, XID mode, QPoint position);
//friend int Output::changeConfiguration(bool active, XID mode, QPoint position);
public:
Crtc(XID, Screen*);
// Getter
inline const OutputList & getConnectedOutputs( ) { return _outputs; }
inline const QRect getRect() { return _crtcRect; }
// Setter
// Applies the changes made to this crtc
// int applyChanges();
// void disable();
// void connect(const Output *, Mode);
private:
Screen *_parent;
// Indicates when the configuration was last set.
Time _timestamp;
// 'x' and 'y' indicate the position of this CRTC within the screen
// region. They will be set to 0 when the CRTC is disabled.
// 'width' and 'height' indicate the size of the area within the screen
// presented by this CRTC. This may be different than the size of the
// mode due to rotation, the projective transform, and the Border
// property described below.
// They will be set to 0 when the CRTC is disabled.
QRect _crtcRect;
// Indicates which mode is active, or None indicating that the
// CRTC has been disabled and is not displaying the screen contents.
RRMode _mode;
// The list of outputs currently connected to this CRTC,
// is empty when the CRTC is disabled.
OutputList _outputs;
// Lists all of the outputs which may be connected to this CRTC.
OutputList _possible;
// The active rotation. Set to Rotate_0 when the CRTC is disabled.
Rotation _rotation;
// enum Rotation {
// Normal = RR_Rotate_0,
// Left = RR_Rotate_270,
// Right = RR_Rotate_90,
// UpsideDown = RR_Rotate_180
// };
// contains the set of rotations and reflections supported by the CRTC
Rotation _rotations;
};
}
#endif // XRANDR_H