diff options
-rw-r--r-- | src/beamergui.pro | 27 | ||||
-rw-r--r-- | src/displaymanager.cpp | 36 | ||||
-rw-r--r-- | src/displaymanager.h | 32 | ||||
-rw-r--r-- | src/main.cpp | 11 | ||||
-rw-r--r-- | src/output.cpp | 119 | ||||
-rw-r--r-- | src/output.h | 47 | ||||
-rw-r--r-- | src/widget.cpp | 145 | ||||
-rw-r--r-- | src/widget.h | 31 | ||||
-rw-r--r-- | src/widget.ui | 39 |
9 files changed, 487 insertions, 0 deletions
diff --git a/src/beamergui.pro b/src/beamergui.pro new file mode 100644 index 0000000..936b664 --- /dev/null +++ b/src/beamergui.pro @@ -0,0 +1,27 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-10-14T14:24:40 +# +#------------------------------------------------- + +QT += core gui + +TARGET = beamergui +TEMPLATE = app + + +SOURCES += main.cpp\ + widget.cpp \ + output.cpp \ + displaymanager.cpp + +HEADERS += \ + widget.h \ + output.h \ + displaymanager.h + +FORMS += widget.ui + + +LIBS += -lXrandr -lX11 + diff --git a/src/displaymanager.cpp b/src/displaymanager.cpp new file mode 100644 index 0000000..61f35ea --- /dev/null +++ b/src/displaymanager.cpp @@ -0,0 +1,36 @@ +#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 new file mode 100644 index 0000000..775b87b --- /dev/null +++ b/src/displaymanager.h @@ -0,0 +1,32 @@ +#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 new file mode 100644 index 0000000..cb48fbb --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,11 @@ +#include <QtGui/QApplication> +#include "widget.h" + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + return a.exec(); +} diff --git a/src/output.cpp b/src/output.cpp new file mode 100644 index 0000000..94f6c89 --- /dev/null +++ b/src/output.cpp @@ -0,0 +1,119 @@ +#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 new file mode 100644 index 0000000..553444d --- /dev/null +++ b/src/output.h @@ -0,0 +1,47 @@ +#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 new file mode 100644 index 0000000..7867f92 --- /dev/null +++ b/src/widget.cpp @@ -0,0 +1,145 @@ +#include "widget.h" +#include "ui_widget.h" +#include "displaymanager.h" + + +//#include <QString> +//#include <QSet> +//#include <QDebug> +#include <vector> +using namespace std; + +#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) + { + 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; + } + } + + + + + +// 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()); + } + + Widget::~Widget() + { + delete ui; + } + + void Widget::configureWidgetForBeamerWithEDID() + { + } + + void Widget::configureWidgetForBeamerWithOUTEDID() + { + } diff --git a/src/widget.h b/src/widget.h new file mode 100644 index 0000000..fc8570a --- /dev/null +++ b/src/widget.h @@ -0,0 +1,31 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include <QWidget> +#include <QtGui> + +#include <X11/Xlib.h> +#include <X11/extensions/Xrandr.h> + +namespace Ui { +class Widget; +} + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + +private: + + Ui::Widget * ui; + + void configureWidgetForBeamerWithEDID(); + void configureWidgetForBeamerWithOUTEDID(); + +}; + +#endif // WIDGET_H diff --git a/src/widget.ui b/src/widget.ui new file mode 100644 index 0000000..cfa9bdf --- /dev/null +++ b/src/widget.ui @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="QWidget" name="Widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="comboBox"/> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> |