From 9a9ffe7eebf14ea1828480c2e175e4fc39e26dac Mon Sep 17 00:00:00 2001 From: Manuel Schneider Date: Fri, 18 Oct 2013 11:25:12 +0200 Subject: [Incomplete] Commit for EDID testsystem --- src/beamergui.pro | 27 +++++++++ src/displaymanager.cpp | 36 ++++++++++++ src/displaymanager.h | 32 +++++++++++ src/main.cpp | 11 ++++ src/output.cpp | 119 ++++++++++++++++++++++++++++++++++++++++ src/output.h | 47 ++++++++++++++++ src/widget.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ src/widget.h | 31 +++++++++++ src/widget.ui | 39 +++++++++++++ 9 files changed, 487 insertions(+) create mode 100644 src/beamergui.pro create mode 100644 src/displaymanager.cpp create mode 100644 src/displaymanager.h create mode 100644 src/main.cpp create mode 100644 src/output.cpp create mode 100644 src/output.h create mode 100644 src/widget.cpp create mode 100644 src/widget.h create mode 100644 src/widget.ui 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 +#include "output.h" + +#include +using namespace std; + +class DisplayManager +{ +public: + + inline vector& getConnectedOutputs(){ return Outputs; } + +private: + + Display *dpy; + XRRScreenResources *resources; + vector 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 +#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 + +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 Output::getSupportedModes() const +{ + QSet 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 +#include + +#include +#include + +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 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 +//#include +//#include +#include +using namespace std; + +#include + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + + DisplayManager* DM = DisplayManager::Inst(); + + for (std::vector::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 modes = (*i).getSupportedModes(); + for ( QSet::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 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::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::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 +#include + +#include +#include + +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 @@ + + + Widget + + + + 0 + 0 + 600 + 480 + + + + + 0 + 0 + + + + + + + + + + + + PushButton + + + + + + + + + + + -- cgit v1.2.3-55-g7522