summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorManuel Schneider2013-11-21 15:38:19 +0100
committerManuel Schneider2013-11-21 15:38:19 +0100
commit21aa80032f685b3ded10fe293ca083d2f46ae18c (patch)
tree5f43f8791996dc445cedf51e4bcbe913fa908b12 /src
parent[Incomplete] Commit for EDID testsystem (diff)
downloadbeamergui-21aa80032f685b3ded10fe293ca083d2f46ae18c.tar.gz
beamergui-21aa80032f685b3ded10fe293ca083d2f46ae18c.tar.xz
beamergui-21aa80032f685b3ded10fe293ca083d2f46ae18c.zip
alpha
Diffstat (limited to 'src')
-rw-r--r--src/beamer.conf226
-rw-r--r--src/beamergui.pro13
-rw-r--r--src/config.cpp109
-rw-r--r--src/config.h45
-rw-r--r--src/displaymanager.cpp36
-rw-r--r--src/displaymanager.h32
-rw-r--r--src/main.cpp420
-rw-r--r--src/output.cpp119
-rw-r--r--src/output.h47
-rw-r--r--src/widget.cpp201
-rw-r--r--src/widget.h14
-rw-r--r--src/x.cpp473
-rw-r--r--src/x.h281
13 files changed, 1446 insertions, 370 deletions
diff --git a/src/beamer.conf2 b/src/beamer.conf2
new file mode 100644
index 0000000..0cf780f
--- /dev/null
+++ b/src/beamer.conf2
@@ -0,0 +1,26 @@
+# 16:10
+Modeline 83.50 1280 1352 1480 1680 800 803 809 831 -hsync +vsync
+Modeline 106.50 1440 1528 1672 1904 900 903 909 934 -hsync +vsync
+Modeline 146.25 1680 1784 1960 2240 1050 1053 1059 1089 -hsync +vsync
+Modeline 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync
+Modeline 348.50 2560 2760 3032 3504 1600 1603 1609 1658 -hsync +vsync
+
+# 16:9
+Modeline 74.50 1280 1344 1472 1664 720 723 728 748 -hsync +vsync
+Modeline 85.25 1368 1440 1576 1784 768 771 781 798 -hsync +vsync
+Modeline 118.25 1600 1696 1856 2112 900 903 908 934 -hsync +vsync
+Modeline 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
+Modeline 312.25 2560 2752 3024 3488 1440 1443 1448 1493 -hsync +vsync
+
+# 4:3
+Modeline 38.25 800 832 912 1024 600 603 607 624 -hsync +vsync
+Modeline 63.50 1024 1072 1176 1328 768 771 775 798 -hsync +vsync
+Modeline 81.75 1152 1216 1336 1520 864 867 871 897 -hsync +vsync
+Modeline 101.25 1280 1360 1488 1696 960 963 967 996 -hsync +vsync
+Modeline 121.75 1400 1488 1632 1864 1050 1053 1057 1089 -hsync +vsync
+
+# Display to use
+Display :0
+
+# IP specific configs
+IP 132.230.4.100 1280x900
diff --git a/src/beamergui.pro b/src/beamergui.pro
index 936b664..6c1fbdc 100644
--- a/src/beamergui.pro
+++ b/src/beamergui.pro
@@ -12,16 +12,15 @@ TEMPLATE = app
SOURCES += main.cpp\
widget.cpp \
- output.cpp \
- displaymanager.cpp
+ config.cpp \
+ x.cpp
-HEADERS += \
- widget.h \
- output.h \
- displaymanager.h
+HEADERS += widget.h \
+ displaymanager.h \
+ config.h \
+ x.h
FORMS += widget.ui
LIBS += -lXrandr -lX11
-
diff --git a/src/config.cpp b/src/config.cpp
new file mode 100644
index 0000000..1e3f827
--- /dev/null
+++ b/src/config.cpp
@@ -0,0 +1,109 @@
+#include <QDebug>
+#include <QStringList>
+#include <stdio.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include "config.h"
+
+#define GROUP_GENERAL "General"
+#define GROUP_MODELINES "Modelines"
+#define GROUP_SPECIFIC "SpecificSettings"
+#define DISPLAY_KEY "display"
+#define DISPLAY_DEFAULT ":0"
+#define IFACE_KEY "interface"
+#define IFACE_DEFAULT "eth0"
+
+Config * Config::Instance = NULL;
+
+//_____________________________________________________________________________
+
+
+Config::Config()
+{
+ // Defaults
+ display = ":0";
+ interface = "eth0";
+}
+
+//_____________________________________________________________________________
+
+
+void Config::loadSettings(QString _file)
+{
+ // Open setting file
+ settingsPath = _file;
+ QSettings settings(settingsPath, QSettings::NativeFormat);
+
+ // Get general information
+ settings.beginGroup(GROUP_GENERAL);
+ display = settings.value(DISPLAY_KEY, DISPLAY_DEFAULT).toString();
+ interface = settings.value(IFACE_KEY, IFACE_DEFAULT).toString();
+ settings.endGroup();
+
+
+ /* Check for ip specific settings */
+
+ // Get local ip
+ QString IPV4 = getIPV4ofInterface(interface);
+
+ // Find any information saved about this ip
+ settings.beginGroup(GROUP_SPECIFIC);
+ if ( settings.contains(IPV4) )
+ ipSpecificXConf = settings.value(IPV4).toStringList();
+ settings.endGroup();
+
+
+ /* Get the "must-have-modelines" */
+
+ settings.beginGroup(GROUP_MODELINES);
+
+ // Get all keys in this group (Keys are modenames)
+ QStringList modeKeys = settings.allKeys();
+
+ // Get the modeline for each key
+ for (QStringList::const_iterator i = modeKeys.constBegin(); i != modeKeys.constEnd(); ++i)
+ {
+ // Prepend the name and save in list
+ modeLines.insert(*i, settings.value(*i).toStringList());
+ }
+ settings.endGroup();
+
+}
+
+//_____________________________________________________________________________
+
+
+QString Config::getIPV4ofInterface(QString _if) const
+{
+ struct ifaddrs * ifAddrStruct=NULL;
+ struct ifaddrs * ifa=NULL;
+ void * tmpAddrPtr=NULL;
+ QString result;
+
+ getifaddrs(&ifAddrStruct);
+
+ // Iterate through the adresses.
+ for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ // If the address is IP V4 and the interface is _if
+ if (ifa ->ifa_addr->sa_family==AF_INET && ( strcmp(ifa->ifa_name, _if.toUtf8().constData()) == 0) )
+ {
+ // Get the IP
+ tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
+
+ // convert to readable form
+ char addressBuffer[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
+ result = addressBuffer;
+ }
+ }
+
+ // clean up
+ if (ifAddrStruct!=NULL)
+ freeifaddrs(ifAddrStruct);
+
+ return result;
+}
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..20f67d3
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,45 @@
+#ifndef CONIG_H
+#define CONIG_H
+
+#include <QString>
+#include <QList>
+#include <QStringList>
+#include <QMap>
+#include <QSettings>
+
+#define CONFIG_PATH "/home/manuel/beamer.conf"
+
+class Config
+{
+ Config();
+ ~Config();
+
+ static Config * Instance;
+
+ QString settingsPath;
+ QString display;
+ QString interface;
+ QStringList ipSpecificXConf;
+ QMap<QString, QStringList> modeLines;
+
+ QString getIPV4ofInterface(QString) const;
+
+public:
+
+ void loadSettings(QString);
+
+ // Getters
+ inline const QString& getSettingsPath() { return settingsPath; }
+ inline const QString& getDisplay() { return display; }
+ inline const QString& getInterface() { return interface; }
+ inline const QStringList& getIpSpecificXConf(){ return ipSpecificXConf; }
+ inline const QMap<QString, QStringList>& getModeLines() { return modeLines; }
+
+ // Singleton //
+ inline static Config * inst() {
+ if (Instance == NULL) Instance = new Config();
+ return Instance;
+ }
+};
+
+#endif // CONIG_H
diff --git a/src/displaymanager.cpp b/src/displaymanager.cpp
deleted file mode 100644
index 61f35ea..0000000
--- a/src/displaymanager.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "displaymanager.h"
-
-
-DisplayManager * DisplayManager::Instance = NULL;
-
-DisplayManager::DisplayManager()
-{
- dpy = NULL;
- resources = NULL;
-
-
- // Get initial data (to be freed)
- dpy = XOpenDisplay(NULL);
- resources = XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy));
-
- // Get outputs
- for (int i = 0; i < resources->noutput; ++i) {
- XRROutputInfo *info = XRRGetOutputInfo (dpy, resources, resources->outputs[i]);
- if (info->connection == RR_Connected)
- Outputs.push_back(Output(dpy, resources, resources->outputs[i]));
- XRRFreeOutputInfo(info);
- }
-}
-
-DisplayManager::~DisplayManager()
-{
- XCloseDisplay(dpy);
- XRRFreeScreenResources(resources);
-}
-
-DisplayManager *DisplayManager::Inst()
-{
- if (Instance == 0)
- Instance = new DisplayManager();
- return Instance;
-}
diff --git a/src/displaymanager.h b/src/displaymanager.h
deleted file mode 100644
index 775b87b..0000000
--- a/src/displaymanager.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef DISPLAYMANAGER_H
-#define DISPLAYMANAGER_H
-
-#include <QDebug>
-#include "output.h"
-
-#include <vector>
-using namespace std;
-
-class DisplayManager
-{
-public:
-
- inline vector<Output>& getConnectedOutputs(){ return Outputs; }
-
-private:
-
- Display *dpy;
- XRRScreenResources *resources;
- vector<Output> Outputs;
-
-
-/** Singleton pattern **/
-public:
- static DisplayManager * Inst();
-private:
- static DisplayManager * Instance;
- DisplayManager();
- ~DisplayManager();
-};
-
-#endif // DISPLAYMANAGER_H
diff --git a/src/main.cpp b/src/main.cpp
index cb48fbb..9c95f7c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,11 +1,431 @@
+
+
#include <QtGui/QApplication>
+#include <QString>
+#include <QDebug>
+#include <fstream>
+#include <iostream>
#include "widget.h"
+#include "config.h"
+#include "x.h"
+
+
+// Prototypes
+QString getIP ();
+
+void usage()
+{
+}
int main(int argc, char *argv[])
{
+// ///////////////////
+// // Debug
+// argv[1] = "/home/manuel/beamer.conf";
+// ///////////////////7
+
+// if ( argc < 1 )
+// {
+// std::cerr << "Too many arguments. The only parameter shall be a path to a config file." << std::endl;
+// exit(1);
+// }
+// if ( argc == 1 )
+// {
+// // Check if file exists
+// std::ifstream f(argv[1]);
+// if (!f)
+// {
+// std::cerr << "The config file does not exist" << std::endl;
+// exit(1);
+// }
+// else
+// f.close();
+// }
+
+// //Load settings
+// Config::inst()->loadSettings(argv[1]);
+// qDebug() << X::Screen::inst();
+
+
+// qDebug() << Config::inst()->getDisplay();
+// qDebug() << Config::inst()->getInterface();
+// qDebug() << Config::inst()->getIpSpecificXConf();
+// qDebug() << Config::inst()->getModeLines();
+// qDebug() << Config::inst()->getSettingsPath();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// // Get initial data (to be freed)
+// Display *dpy = XOpenDisplay(NULL);
+// XRRScreenResources *sr = XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy));
+
+
+
+
+// int X=1;RandR::
+// int M=1;
+
+// XRROutputInfo *output_first_info = XRRGetOutputInfo(dpy, sr, sr->outputs[X]);
+
+// // XRRSet
+// // HOLY
+// XRRSetCrtcConfig(dpy,
+// sr,
+// output_first_info->crtc,
+// CurrentTime,
+// 0, 0,
+// sr->modes[output_first_info->npreferred -1].id,
+// RR_Rotate_0,
+// &sr->outputs[X],
+// 1);
+
+
+
+
+
+
+
+
+
+
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
+
+
+
+
+////////////////////////////////////////// CODE MÜLLEIMER
+
+
+ // eine datei
+
+
+//Widget::Widget(QWidget *parent) :
+// QWidget(parent),
+// ui(new Ui::Widget)
+//{
+// ui->setupUi(this);
+
+// for (std::vector<Output>::iterator i = DisplayManager::Inst()->getConnectedOutputs().begin();
+// i != DisplayManager::Inst()->getConnectedOutputs().end();
+// ++i)
+// {
+// qDebug() << "EDID?" << ( (*i).hasEDID() ? "true" : "false");
+// qDebug() << "Proj?" << ( (*i).isProjector() ? "true" : "false");
+// qDebug() << "Current?"
+// << DisplayManager::Inst()->getResolution((*i).getCurrentMode()).width
+// << DisplayManager::Inst()->getResolution((*i).getCurrentMode()).height;
+// Resolution res;
+// if ((*i).getPreferredMode())
+// qDebug() << "Preferred?"
+// << DisplayManager::Inst()->getResolution((*i).getPreferredMode()).width
+// << DisplayManager::Inst()->getResolution((*i).getPreferredMode()).height;
+
+// QSet<RRMode> modes = (*i).getSupportedModes();
+
+// for ( QSet<RRMode>::iterator i = modes.begin(); i != modes.end(); ++i )
+// {
+// qDebug() << "---- "
+// << DisplayManager::Inst()->getResolution(*i).width
+// << DisplayManager::Inst()->getResolution(*i).height;
+// }
+// }
+
+
+// switch ( DisplayManager::Inst()->getConnectedOutputs().size() ){
+// /*************************************************************************/
+// case 1:// In case of one connected output - xrandr --auto
+// qDebug() << "Normal output";
+// exit(0);
+// break;
+// /*************************************************************************/
+// case 2: // In case of two connected outputs
+
+// /*********************************************************************/
+// // If one of the two connected outputs is a beamer
+
+// if ( true)//DisplayManager::Inst()->isProjectorConnected() )
+// {
+// /*
+// Here the usecases have to be listed theoretically there are two
+// in this case. 2 Projectors, 1 projectors and on monitor. Only the
+// latter is asumed here.
+// */
+
+// // Remember which one is the projector
+// int ProjectorIndex;
+// DisplayManager::Inst()->getConnectedOutputs().at(0).isProjector()
+// ? ProjectorIndex = 0 : ProjectorIndex = 0;
+
+// /*****************************************************************/
+// // If the beamer transmits reliable EDID data.
+// if( DisplayManager::Inst()->getConnectedOutputs().at(ProjectorIndex).hasEDID() )
+// {
+// // Now we can assume that the preferred mode of the projector to be correnct
+// // to be correct.
+
+// // Get the AR of the beamer
+// Resolution res;
+// if ( DisplayManager::Inst()->getConnectedOutputs().at(ProjectorIndex).getPreferredMode() )
+// fprintf(stderr, "Beamer has EDID but no preferred mode.");
+
+// float AR = res.width/res.height;
+
+// QSet<RRMode> BeamerModes =
+// DisplayManager::Inst()->getConnectedOutputs().at(ProjectorIndex).getSupportedModes();
+
+// QSet<RRMode> MonitorModes =
+// DisplayManager::Inst()->getConnectedOutputs().at(1-ProjectorIndex).getSupportedModes();
+
+// QSet<RRMode> CommonModes = BeamerModes.unite(MonitorModes);
+
+// CommonModes.intersect(BeamerModes);
+// CommonModes.intersect(MonitorModes);
+
+// // Fill treewidget with data from cups dests;
+// for ( QSet<RRMode>::iterator i = CommonModes.begin(); i != CommonModes.end(); ++i )
+// {
+// char * ModeString;
+// sprintf(ModeString, "%dx%d",
+// DisplayManager::Inst()->getResolution(*i).width,
+// DisplayManager::Inst()->getResolution(*i).height
+// );
+
+// qDebug() << ModeString;
+// ui->comboBox->addItem(ModeString, QVariant((unsigned long long int)*i));
+// }
+// }
+// /*****************************************************************/
+// // If the beamer DOES NOT transmits reliable EDID data.
+// else
+// {
+// qDebug() << "beamer output no reliable EDID ";
+// configureWidgetForBeamerWithEDID();
+// }
+// /*****************************************************************/
+
+// }
+// /*********************************************************************/
+// // If NEITHER of the outputs is a beamer (likely dualscreen setup)
+// else
+// {
+// // Just apply preferred settings
+
+// qDebug() << "dualscreen output";
+
+// }
+// break;
+// /*************************************************************************/
+// default:
+// // If there are more than 3 outputs
+// // its up to the user. Quit.
+// exit(0);
+// break;
+// }
+// /*************************************************************************/
+
+
+
+
+
+
+// //Remove borders and stuff
+// setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
+
+
+
+
+// // QSet<RRMode> outputs0, outputs1;
+// // for (int i = 0; i < XManager::Inst()->getOutputInfos()[0]->nmode; ++i)
+// // outputs0.insert(XManager::Inst()->getOutputInfos()[0]->modes[i]);
+// // for (int i = 0; i < XManager::Inst()->getOutputInfos()[1]->nmode; ++i)
+// // outputs1.insert(XManager::Inst()->getOutputInfos()[1]->modes[i]);
+// // outputs0.intersect(outputs1);
+
+// // // Fill treewidget with data from cups dests;
+// // for ( QSet<RRMode>::iterator it = outputs0.begin(); it != outputs0.end(); ++it )
+// // {
+// // qDebug() << *it;
+// // qDebug() << XManager::Inst()->getModeMap()[*it];
+// // ui->comboBox->addItem(XManager::Inst()->getModeMap().at(*it), (unsigned long long int)*it);
+// // }
+
+// // // Fill treewidget with data from cups dests;
+// // for ( map<XID, char *>::iterator it = XManager::Inst()->getModeMap().begin(); it != XManager::Inst()->getModeMap().end(); ++it )
+// // {
+// // qDebug() << it->first ;
+// //// qDebug() << XManager::getInstance()->getModeMap()[*it];
+// //// ui->comboBox->addItem(XManager::getInstance()->getModeMap().at(*it), (unsigned long long int)*it);
+// // }
+
+// // Resize widget to its content
+// resize(sizeHint());
+
+// // Center dialog on screenbottom
+// const QRect desktopRect = QApplication::desktop()->screenGeometry();
+// this->move( desktopRect.width()/2-this->width()/2,
+// desktopRect.height()-this->height());
+// }
+
+// Widget::~Widget()
+// {
+// delete ui;
+// }
+
+// void Widget::configureWidgetForBeamerWithEDID()
+// {
+// }
+
+// void Widget::configureWidgetForBeamerWithOUTEDID()
+// {
+// }
+
+
+
+
+
+ // eine andre datei
+
+
+
+
+
+
+//Widget::Widget(QWidget *parent) :
+// QWidget(parent),
+// ui(new Ui::Widget)
+//{
+// ui->setupUi(this);
+
+
+// X11::XManager * XM = X11::XManager::getInstance();
+
+
+// switch ( XM->getOutputInfos().size() ){
+// /*************************************************************************/
+// case 1:// In case of one connected output - xrandr --auto
+// qDebug() << "Normal output";
+// exit(0);
+// break;
+// /*************************************************************************/
+// case 2: // In case of two connected outputs
+
+// /*********************************************************************/
+// // If one of the two connected outputs is a beamer
+// if ( true ) //( XM->getOutputInfos()[0]->mm_width == 0 && XM->getOutputInfos()[0]->mm_height == 0 )
+// // || ( XM->getOutputInfos()[1]->mm_width == 0 && XM->getOutputInfos()[1]->mm_height == 0 ) )
+// {
+// /*****************************************************************/
+// // If the beamer transmits reliable EDID data.
+// if( isReliableEDIDpresent() )
+// {
+// qDebug() << "beamer output reliable EDID ";
+// configureWidgetForBeamerWithEDID();
+// }
+// /*****************************************************************/
+// // If the beamer DOES NOT transmits reliable EDID data.
+// else
+// {
+// qDebug() << "beamer output no reliable EDID ";
+// configureWidgetForBeamerWithEDID();
+// }
+// /*****************************************************************/
+
+// }
+// /*********************************************************************/
+// // If NEITHER of the outputs is a beamer (likely dualscreen setup)
+// else
+// {
+// // Just apply preferred settings
+// qDebug() << "dualscreen output";
+
+// }
+// break;
+// /*************************************************************************/
+// default:
+// // If there are more than 3 outputs
+// // its up to the user. Quit.
+// exit(0);
+// break;
+// }
+// /*************************************************************************/
+
+
+
+
+// Remove borders and stuff
+// setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
+
+
+
+
+// QSet<RRMode> outputs0, outputs1;
+// for (int i = 0; i < XManager::Inst()->getOutputInfos()[0]->nmode; ++i)
+// outputs0.insert(XManager::Inst()->getOutputInfos()[0]->modes[i]);
+// for (int i = 0; i < XManager::Inst()->getOutputInfos()[1]->nmode; ++i)
+// outputs1.insert(XManager::Inst()->getOutputInfos()[1]->modes[i]);
+// outputs0.intersect(outputs1);
+
+// // Fill treewidget with data from cups dests;
+// for ( QSet<RRMode>::iterator it = outputs0.begin(); it != outputs0.end(); ++it )
+// {
+// qDebug() << *it;
+// qDebug() << XManager::Inst()->getModeMap()[*it];
+// ui->comboBox->addItem(XManager::Inst()->getModeMap().at(*it), (unsigned long long int)*it);
+// }
+
+// // Fill treewidget with data from cups dests;
+// for ( map<XID, char *>::iterator it = XManager::Inst()->getModeMap().begin(); it != XManager::Inst()->getModeMap().end(); ++it )
+// {
+// qDebug() << it->first ;
+//// qDebug() << XManager::getInstance()->getModeMap()[*it];
+//// ui->comboBox->addItem(XManager::getInstance()->getModeMap().at(*it), (unsigned long long int)*it);
+// }
+
+// // Resize widget to its content
+// resize(sizeHint());
+
+// // Center dialog on screenbottom
+// const QRect desktopRect = QApplication::desktop()->screenGeometry();
+// this->move( desktopRect.width()/2-this->width()/2,
+// desktopRect.height()-this->height());
+//}
+
+
diff --git a/src/output.cpp b/src/output.cpp
deleted file mode 100644
index 94f6c89..0000000
--- a/src/output.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "output.h"
-#include "stdio.h"
-
-
-//DEVUTG
-#include <inttypes.h>
-
-Output::Output(Display *dpy, XRRScreenResources *resources, RROutput output)
- :dpy(dpy), resources(resources), ID(output)
-{
-
-}
-
-
-bool Output::hasEDID() const
-{
- int nprop;
- Atom *props = XRRListOutputProperties(dpy, ID, &nprop);
- Atom actual_type;
- int actual_format;
- unsigned long nitems, bytes_after;
- unsigned char *prop;
- XRRPropertyInfo *propinfo;
- int bytes_per_item, k;
-
- for (int i = 0; i < nprop; ++i) {
- char *atom_name = XGetAtomName (dpy, props[i]);
- if ( strcmp (atom_name, "EDID") == 0)
- {
- fprintf (stderr, "EDIDCHECK");
- XRRGetOutputProperty (dpy, ID, props[i],
- 0, 100, False, False,
- AnyPropertyType,
- &actual_type, &actual_format,
- &nitems, &bytes_after, &prop);
-
- propinfo = XRRQueryOutputProperty(dpy, ID, props[i]);
- bytes_per_item = actual_format / 8;
-
- fprintf (stderr, "\t%s: ", atom_name);
-
- for (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);
- return true;
- }
- }
-
-}
-
-
-
-bool Output::isProjector() const
-{
- XRROutputInfo *info = XRRGetOutputInfo (dpy, resources, ID);
- bool result = ( info->mm_height == 0 && info->mm_width == 0 );
- XRRFreeOutputInfo(info);
- return result;
-}
-
-Resolution Output::getCurrentMode() const
-{
- XRROutputInfo *OutputInfo = XRRGetOutputInfo (dpy, resources, ID);
- XRRCrtcInfo *CrtcInfo = XRRGetCrtcInfo(dpy, resources, OutputInfo->crtc);
- Resolution result = { CrtcInfo->width, CrtcInfo->height };
- XRRFreeCrtcInfo(CrtcInfo);
- XRRFreeOutputInfo(OutputInfo);
- return result;
-}
-
-
-Resolution Output::getPreferredMode() const
-{
- XRROutputInfo *OutputInfo = XRRGetOutputInfo (dpy, resources, ID);
- RRMode preferred = OutputInfo->modes[OutputInfo->npreferred];
- XRRFreeOutputInfo(OutputInfo);
- return getResolution(preferred);
-}
-
-
-QSet<Resolution> Output::getSupportedModes() const
-{
- QSet<Resolution> result;
- XRROutputInfo *info = XRRGetOutputInfo (dpy, resources, ID);
- for (int i = 0; i < info->nmode; ++i)
- result.insert(getResolution(info->modes[i]));
- XRRFreeOutputInfo(info);
- return result;
-}
-
-
-Resolution Output::addMode(Resolution) const
-{
- // TODO
- return Resolution();
-}
-
-Resolution Output::getResolution(RRMode mode) const
-{
- for (int i = 0; i < resources->nmode; ++i) {
- if ( resources->modes[i].id == mode ) {
- Resolution res = {resources->modes[i].width, resources->modes[i].height};
- return res;
- }
- }
- fprintf ( stderr, "Could not find a mode for the requested XID %d", (int)mode);
- exit(1);
-}
diff --git a/src/output.h b/src/output.h
deleted file mode 100644
index 553444d..0000000
--- a/src/output.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef OUTPUT_H
-#define OUTPUT_H
-
-#include <QDebug>
-#include <QSet>
-
-#include <X11/Xlib.h>
-#include <X11/extensions/Xrandr.h>
-
-typedef struct _Resolution{
- unsigned int width;
- unsigned int height;
-}Resolution;
-
-inline bool operator==(const Resolution& lhs, const Resolution& rhs) {
- return lhs.width == rhs.width && lhs.height == rhs.height;
-}
-
-inline uint qHash(const Resolution &key)
-{
- return qHash(key.width ^ key.height);
-}
-
-class Output
-{
-public:
-
-
- Output(Display *dpy, XRRScreenResources *resources, RROutput output);
-
- bool hasEDID() const;
- bool isProjector() const;
- Resolution getCurrentMode() const;
- Resolution getPreferredMode() const;
- QSet<Resolution> getSupportedModes() const;
- Resolution addMode(Resolution) const;
-
-private:
-
- Display *dpy;
- XRRScreenResources *resources;
- RROutput ID;
-
- Resolution getResolution(RRMode) const;
-};
-
-#endif // OUTPUT_H
diff --git a/src/widget.cpp b/src/widget.cpp
index 7867f92..994f3d1 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -1,145 +1,98 @@
#include "widget.h"
#include "ui_widget.h"
-#include "displaymanager.h"
-
-
-//#include <QString>
-//#include <QSet>
-//#include <QDebug>
-#include <vector>
-using namespace std;
+#include <QString>
+#include <QSet>
#include <algorithm>
+
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
- ui->setupUi(this);
-
- DisplayManager* DM = DisplayManager::Inst();
-
- for (std::vector<Output>::iterator i = DM->getConnectedOutputs().begin(); i != DM->getConnectedOutputs().end(); ++i)
+ ui->setupUi(this);
+
+ X::OutputList outputs = X::Screen::inst()->getConnectedOutputList();
+
+ switch ( X::Screen::inst()->getConnectedOutputList().size() ){
+ /*************************************************************************/
+ case 1:// In case of one connected output - xrandr --auto
+ qDebug() << "Normal output";
+ exit(0);
+ break;
+ /*************************************************************************/
+ case 2: // In case of two connected outputs
+
+ // If one of the two connected outputs is a beamer
+ if (true)
+ //X::Screen::inst()->getOutputMap()[outputs[0]]->isProjector()
+ // || X::Screen::inst()->getOutputMap()[outputs[1]]->isProjector() )
{
- qDebug() << "EDID?" << ( (*i).hasEDID() ? "true" : "false");
- qDebug() << "Proj?" << ( (*i).isProjector() ? "true" : "false");
- qDebug() << "Current?" << (*i).getCurrentMode().width<< (*i).getCurrentMode().height;
- qDebug() << "Preferred?" << (*i).getPreferredMode().width << (*i).getPreferredMode().height;
- QSet<Resolution> modes = (*i).getSupportedModes();
- for ( QSet<Resolution>::iterator i = modes.begin(); i != modes.end(); ++i )
- {
- qDebug() << "---- " << (*i).width << (*i).height;
- }
+ qDebug() << "Cloned output";
+ /*****************************************************************/
+ // If the beamer transmits no reliable EDID data add modes
+ if ( ! ( X::Screen::inst()->getOutputMap()[outputs[0]]->hasReliableEDID()
+ && X::Screen::inst()->getOutputMap()[outputs[1]]->hasReliableEDID() ) )
+ {
+ // TODO ADD MODES
+ qDebug() << "Normal output";
+ }
+
+ // Get a set of unique modes as string. Ugly but same resolutions may
+ // have different ids. This means modes are compared by name which is
+ X::ModeSet ModeSet1 = X::Screen::inst()->getOutputMap()[outputs[0]]->getModeSet();
+ X::ModeSet ModeSet2 = X::Screen::inst()->getOutputMap()[outputs[1]]->getModeSet();
+ QSet<QString> ModeNames1, ModeNames2;
+ for (X::ModeSet::iterator i = ModeSet1.begin();
+ i != ModeSet1.end(); ++i)
+ ModeNames1.insert(X::Screen::inst()->getModeMap()[*i]._name);
+ for (X::ModeSet::iterator i = ModeSet2.begin();
+ i != ModeSet2.end(); ++i)
+ ModeNames2.insert(X::Screen::inst()->getModeMap()[*i]._name);
+ ModeNames1.intersect(ModeNames2);
+
+ // Fill widget with data
+ for ( QSet<QString>::iterator i = ModeNames1.begin(); i != ModeNames1.end(); ++i )
+ ui->comboBox->addItem(*i);
}
+ /*********************************************************************/
+ // If NEITHER of the outputs is a beamer (likely dualscreen setup)
+ else
+ {
+ // TODO(manuel): Furture feature. Setup dualscreen
+ qDebug() << "Dual output";
+ exit(0);
+ }
+ break;
+ /*************************************************************************/
+ default:
+ // If there are more than 3 outputs
+ // its up to the user. Quit.
+ qDebug() << ">2 outputs. Quit.";
+ exit(0);
+ break;
+ }
+ /*************************************************************************/
-// XManager * XM = XManager::Inst();
-
-
-// switch ( XM->getOutputInfos().size() ){
-// /*************************************************************************/
-// case 1:// In case of one connected output - xrandr --auto
-// qDebug() << "Normal output";
-// exit(0);
-// break;
-// /*************************************************************************/
-// case 2: // In case of two connected outputs
-
-// /*********************************************************************/
-// // If one of the two connected outputs is a beamer
-// if ( true ) //( XM->getOutputInfos()[0]->mm_width == 0 && XM->getOutputInfos()[0]->mm_height == 0 )
-// // || ( XM->getOutputInfos()[1]->mm_width == 0 && XM->getOutputInfos()[1]->mm_height == 0 ) )
-// {
-// /*****************************************************************/
-// // If the beamer transmits reliable EDID data.
-// if( isReliableEDIDpresent() )
-// {
-// qDebug() << "beamer output reliable EDID ";
-// configureWidgetForBeamerWithEDID();
-// }
-// /*****************************************************************/
-// // If the beamer DOES NOT transmits reliable EDID data.
-// else
-// {
-// qDebug() << "beamer output no reliable EDID ";
-// configureWidgetForBeamerWithEDID();
-// }
-// /*****************************************************************/
-
-// }
-// /*********************************************************************/
-// // If NEITHER of the outputs is a beamer (likely dualscreen setup)
-// else
-// {
-// // Just apply preferred settings
-// qDebug() << "dualscreen output";
-
-// }
-// break;
-// /*************************************************************************/
-// default:
-// // If there are more than 3 outputs
-// // its up to the user. Quit.
-// exit(0);
-// break;
-// }
-// /*************************************************************************/
-
-
-
-
-
-
- //Remove borders and stuff
- setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
-
-
-
-
- // QSet<RRMode> outputs0, outputs1;
- // for (int i = 0; i < XManager::Inst()->getOutputInfos()[0]->nmode; ++i)
- // outputs0.insert(XManager::Inst()->getOutputInfos()[0]->modes[i]);
- // for (int i = 0; i < XManager::Inst()->getOutputInfos()[1]->nmode; ++i)
- // outputs1.insert(XManager::Inst()->getOutputInfos()[1]->modes[i]);
- // outputs0.intersect(outputs1);
-
- // // Fill treewidget with data from cups dests;
- // for ( QSet<RRMode>::iterator it = outputs0.begin(); it != outputs0.end(); ++it )
- // {
- // qDebug() << *it;
- // qDebug() << XManager::Inst()->getModeMap()[*it];
- // ui->comboBox->addItem(XManager::Inst()->getModeMap().at(*it), (unsigned long long int)*it);
- // }
-
- // // Fill treewidget with data from cups dests;
- // for ( map<XID, char *>::iterator it = XManager::Inst()->getModeMap().begin(); it != XManager::Inst()->getModeMap().end(); ++it )
- // {
- // qDebug() << it->first ;
- //// qDebug() << XManager::getInstance()->getModeMap()[*it];
- //// ui->comboBox->addItem(XManager::getInstance()->getModeMap().at(*it), (unsigned long long int)*it);
- // }
- // Resize widget to its content
- resize(sizeHint());
- // Center dialog on screenbottom
- const QRect desktopRect = QApplication::desktop()->screenGeometry();
- this->move( desktopRect.width()/2-this->width()/2,
- desktopRect.height()-this->height());
- }
+ // Remove borders and stuff COMMENT FOR DEBUIGGIN
+ //setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
- Widget::~Widget()
- {
- delete ui;
- }
+ // Resize widget to its content
+ resize(sizeHint());
- void Widget::configureWidgetForBeamerWithEDID()
- {
- }
+ // Center dialog on screenbottom
+ const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ this->move( desktopRect.width()/2-this->width()/2,
+ desktopRect.height()-this->height());
+}
- void Widget::configureWidgetForBeamerWithOUTEDID()
- {
- }
+Widget::~Widget()
+{
+ delete ui;
+}
diff --git a/src/widget.h b/src/widget.h
index fc8570a..fff5510 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -3,9 +3,8 @@
#include <QWidget>
#include <QtGui>
-
-#include <X11/Xlib.h>
-#include <X11/extensions/Xrandr.h>
+#include <QDebug>
+#include <x.h>
namespace Ui {
class Widget;
@@ -13,18 +12,23 @@ class Widget;
class Widget : public QWidget
{
+
Q_OBJECT
+
public:
+
explicit Widget(QWidget *parent = 0);
~Widget();
+
+
+public:
+
private:
Ui::Widget * ui;
- void configureWidgetForBeamerWithEDID();
- void configureWidgetForBeamerWithOUTEDID();
};
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);
+//// }
+///////////////////////////////////////////////////////////////////////////////////
diff --git a/src/x.h b/src/x.h
new file mode 100644
index 0000000..4e2265e
--- /dev/null
+++ b/src/x.h
@@ -0,0 +1,281 @@
+#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