aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina/LuminaRandR-X11.cpp
diff options
context:
space:
mode:
authorKen Moore <ken@ixsystems.com>2017-06-22 04:55:42 -0400
committerKen Moore <ken@ixsystems.com>2017-06-22 04:55:42 -0400
commit60b24de5be126f387e5bd4ea654c36e7f0bdd0d4 (patch)
tree9e9bd4b7865f46b0deae7619be296c8994fb8660 /src-qt5/core/libLumina/LuminaRandR-X11.cpp
parentOops - forgot to add the new test.xml file to the last commit. (diff)
parentStart a large update to LuminaRandR info retrieval routine. (diff)
downloadlumina-60b24de5be126f387e5bd4ea654c36e7f0bdd0d4.tar.gz
lumina-60b24de5be126f387e5bd4ea654c36e7f0bdd0d4.tar.bz2
lumina-60b24de5be126f387e5bd4ea654c36e7f0bdd0d4.zip
Merge branch 'master' of github.com:trueos/lumina
Diffstat (limited to 'src-qt5/core/libLumina/LuminaRandR-X11.cpp')
-rw-r--r--src-qt5/core/libLumina/LuminaRandR-X11.cpp269
1 files changed, 171 insertions, 98 deletions
diff --git a/src-qt5/core/libLumina/LuminaRandR-X11.cpp b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
index f8907741..0e68cfd2 100644
--- a/src-qt5/core/libLumina/LuminaRandR-X11.cpp
+++ b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
@@ -6,11 +6,7 @@
//===========================================
#include "LuminaRandR.h"
-//#include "xcb/randr.h"
-//#include "xcb/xcb_atom.h"
-
-#include <QDebug>
-#include <QX11Info>
+//#include "X11/extensions/Xrandr.h"
inline QString atomToName(xcb_atom_t atom){
xcb_get_atom_name_reply_t *nreply = xcb_get_atom_name_reply(QX11Info::connection(), xcb_get_atom_name_unchecked(QX11Info::connection(), atom), NULL);
@@ -27,7 +23,7 @@ inline QStringList atomsToNames(xcb_atom_t *atoms, unsigned int num){
for(unsigned int i=0; i<num; i++){ cookies << xcb_get_atom_name_unchecked(QX11Info::connection(), atoms[i]); }
QStringList names;
//qDebug() << " - Get names";
- for(int i=0; i<cookies.length(); i++){
+ for(int i=0; i<cookies.length(); i++){
xcb_get_atom_name_reply_t *nreply = xcb_get_atom_name_reply(QX11Info::connection(), cookies[i], NULL);
if(nreply==0){ continue; }
names << QString::fromLocal8Bit(xcb_get_atom_name_name(nreply), xcb_get_atom_name_name_length(nreply));
@@ -36,6 +32,52 @@ inline QStringList atomsToNames(xcb_atom_t *atoms, unsigned int num){
return names;
};
+inline bool loadScreenInfo(p_objects *p_obj, xcb_randr_monitor_info_t *info){
+ if(p_obj->monitor_atom == 0){ p_obj->monitor_atom = info->name; }
+ if(p_obj->name.isEmpty()){ p_obj->name = atomToName(info->name); }
+ //Now update all the info in the cache
+ p_obj->primary = (info->primary == 1);
+ p_obj->automatic = (info->automatic == 1);
+ p_obj->geometry = QRect(info->x, info->y, info->width, info->height);
+ p_obj->physicalSizeMM = QSize(info->width_in_millimeters, info->height_in_millimeters);
+ //Load the "outputs"
+ /*p_obj->outputs.clear();
+ int out_len = xcb_randr_monitor_info_outputs_length(info);
+ for(int i=0; i<out_len; i++){ p_obj->outputs << xcb_randr_monitor_info_outputs(info)[i]; }
+ qDebug() << "Info Loaded:" << p_obj->name;
+ for(int i=0; i<p_obj->outputs.length(); i++){*/
+ xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
+ xcb_randr_get_output_info_unchecked(QX11Info::connection(), p_obj->output, QX11Info::appTime()),
+ NULL);
+ if(info==0){ continue; } //bad output
+ //Modes
+ int mode_len = xcb_randr_get_output_info_modes_length(info);
+ //qDebug() << "Number of Modes:" << mode_len;
+ if(mode_len<=0){ continue; } //skip this output - not a physical screen which can be used
+ p_obj->modes.clear();
+ for(int j=0; j<mode_len; j++){
+ p_obj->modes.append( xcb_randr_get_output_info_modes(info)[j] );
+ }
+ //}
+ //qDebug() << "INFO:" << p_obj->name;
+ //qDebug() << "Found Outputs:" << p_obj->outputs;
+ //qDebug() << "Found Modes:" << p_obj->modes;
+ p_obj->resolutions.clear();
+ xcb_randr_get_screen_resources_reply_t *srreply = xcb_randr_get_screen_resources_reply(QX11Info::connection(),
+ xcb_randr_get_screen_resources_unchecked(QX11Info::connection(), QX11Info::appRootWindow()), NULL);
+ if(srreply!=0){
+ for(int i=0; i<xcb_randr_get_screen_resources_modes_length(srreply); i++){
+ xcb_randr_mode_info_t minfo = xcb_randr_get_screen_resources_modes(srreply)[i];
+ if(p_obj->modes.contains(minfo.id)){
+ QSize sz(minfo.width, minfo.height);
+ if(!p_obj->resolutions.contains(sz)){ p_obj->resolutions.append( sz); }
+ }
+ }
+ free(srreply);
+ }
+ return true;
+}
+
/*class OutputDevice::p_objects{
public:
xcb_atom_t monitor_atom; //This is the index used to identify particular monitors (unique ID)
@@ -53,7 +95,7 @@ public:
primary = automatic = false;
monitor_atom = 0;
}
-
+
};*/
//Global Listing of Devices
@@ -62,7 +104,7 @@ QList<OutputDevice> OutputDevice::availableMonitors(){
//Get the list of monitors
xcb_randr_get_monitors_cookie_t cookie = xcb_randr_get_monitors_unchecked(QX11Info::connection(), QX11Info::appRootWindow(), 1);
xcb_randr_get_monitors_reply_t *reply = xcb_randr_get_monitors_reply(QX11Info::connection(), cookie, NULL);
- if(reply==0){
+ if(reply==0){
qDebug() << "Could not get monitor list";
return list;
}
@@ -98,6 +140,13 @@ OutputDevice::OutputDevice(QString id){
p_obj.name = id;
p_obj.primary = p_obj.automatic = false;
p_obj.monitor_atom = 0;
+ p_obj.output = 0;
+ bool ok = false;
+ p_obj.output = id.toInt(&ok);
+ if(ok){
+ //output ID number instead
+ p_obj.name.clear();
+ }
updateInfoCache();
}
@@ -106,13 +155,16 @@ OutputDevice::~OutputDevice(){
}
// INFORMATION FUNCTIONS (simply read from cache)
-QString OutputDevice::ID(){ qDebug() << "Find ID"; return p_obj.name; }
-bool OutputDevice::isEnabled(){ return p_obj.monitor_atom !=0; }
+QString OutputDevice::ID(){ return p_obj.name; }
+bool OutputDevice::isEnabled(){ return !p_obj.geometry.isNull(); }
bool OutputDevice::isPrimary(){ return p_obj.primary; }
bool OutputDevice::isAutomatic(){ return p_obj.automatic; }
+bool OutputDevice::isConnected(){ return !p_obj.modes.isEmpty(); }
+
QList<QSize> OutputDevice::availableResolutions(){ return p_obj.resolutions; }
QSize OutputDevice::currentResolution(){ return p_obj.geometry.size(); } //no concept of panning/scaling yet
QRect OutputDevice::currentGeometry(){ return p_obj.geometry; }
+QSize OutputDevice::physicalSizeMM(){ return p_obj.physicalSizeMM; }
//Modification
bool OutputDevice::setAsPrimary(bool set){
@@ -128,10 +180,22 @@ bool OutputDevice::setAsPrimary(bool set){
}
bool OutputDevice::disable(){
+ //qDebug() << "Disable Monitor:" << p_obj.monitor_atom;
if(p_obj.monitor_atom!=0){
- xcb_randr_delete_monitor(QX11Info::connection(), QX11Info::appRootWindow(), p_obj.monitor_atom);
- p_obj.monitor_atom = 0;
- return true;
+ //qDebug() << " - Go ahead";
+ for(int o=0; o<p_obj.outputs.length(); o++){
+ for(int m=0; m<p_obj.modes.length(); m++){
+ qDebug() << "Deleting Mode for Output:" << "Mode:" << p_obj.modes[m] << "Output:" << p_obj.outputs[o];
+ //XLib version
+ //XRRDeleteOutputMode(QX11Info::display(), p_obj.outputs[o], p_obj.modes[m]);
+ //XCB version
+ xcb_randr_delete_output_mode(QX11Info::connection(), p_obj.outputs[o], p_obj.modes[m]);
+ xcb_flush(QX11Info::connection());
+ }
+ }
+ //xcb_randr_delete_monitor_checked(QX11Info::connection(), QX11Info::appRootWindow(), p_obj.monitor_atom);
+ //p_obj.monitor_atom = 0;
+ return true;
}
return false;
}
@@ -148,53 +212,43 @@ void OutputDevice::changeResolution(QSize){
}
void OutputDevice::updateInfoCache(){
+ xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(QX11Info::connection(),
+ xcb_randr_get_screen_resources_unchecked(QX11Info::connection(), QX11Info::appRootWindow()),
+ NULL);
+ int outputnum = xcb_randr_get_screen_resources_outputs_length(reply);
+ for(int i=0; i<outputnum; i++){
+ xcb_randr_output_t output = xcb_randr_get_screen_resources_outputs(reply)[i];
+ if(p_obj->output==0){
+ //Need to detect the name for this output (inefficient - better to pass in the output number directly)
+ xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
+ xcb_randr_get_output_info_unchecked(QX11Info::connection(), output, QX11Info::appTime()),
+ NULL);
+ //Name
+ QString name = QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info));
+ if(
+ }
+
//Find the **active** monitor with the given id/name
if(p_obj.monitor_atom !=0 || !p_obj.name.isEmpty() ){
- xcb_randr_get_monitors_cookie_t cookie = xcb_randr_get_monitors_unchecked(QX11Info::connection(), QX11Info::appRootWindow(), 1);
- xcb_randr_get_monitors_reply_t *reply = xcb_randr_get_monitors_reply(QX11Info::connection(), cookie, NULL);
- if(reply!=0){
- xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator(reply);
- //qDebug() << "Number of Monitors:" << xcb_randr_get_monitors_monitors_length(reply);
- while(iter.rem>0){
- //qDebug() << " Index:" << iter.index << "Rem:" << iter.rem;
- if( p_obj.monitor_atom == iter.data->name || p_obj.name == atomToName(iter.data->name) ){
- if(p_obj.monitor_atom == 0){ p_obj.monitor_atom = iter.data->name; }
- if(p_obj.name.isEmpty()){ p_obj.name = atomToName(iter.data->name); }
- //Now update all the info in the cache
- p_obj.primary = (iter.data->primary == 1);
- p_obj.automatic = (iter.data->automatic == 1);
- p_obj.geometry = QRect(iter.data->x, iter.data->y, iter.data->width, iter.data->height);
- p_obj.physicalSizeMM = QSize(iter.data->width_in_millimeters, iter.data->height_in_millimeters);
- //Load the "outputs"
- p_obj.outputs.clear();
- int out_len = xcb_randr_monitor_info_outputs_length(iter.data);
- for(int i=0; i<out_len; i++){ p_obj.outputs << xcb_randr_monitor_info_outputs(iter.data)[i]; }
- qDebug() << "Info Loaded:" << p_obj.name;
- //break; //Finished with the information for this particular monitor
+ bool found = false;
+ for(int i=0; i<2 && !found; i++){
+ xcb_randr_get_monitors_cookie_t cookie = xcb_randr_get_monitors_unchecked(QX11Info::connection(), QX11Info::appRootWindow(), (i==0 ? 1 : 0) ); //toggle between active/not monitors
+ xcb_randr_get_monitors_reply_t *reply = xcb_randr_get_monitors_reply(QX11Info::connection(), cookie, NULL);
+ if(reply!=0){
+ xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator(reply);
+ //qDebug() << "Number of Monitors:" << xcb_randr_get_monitors_monitors_length(reply);
+ while(iter.rem>0){
+ if( p_obj.monitor_atom == iter.data->name || p_obj.name == atomToName(iter.data->name) ){
+ loadScreenInfo(&p_obj, iter.data);
+ found = true;
+ break; //Finished with the information for this particular monitor
+ }
+ xcb_randr_monitor_info_next(&iter);
}
- xcb_randr_monitor_info_next(&iter);
- }
- free(reply);
- } //end check for reply structure
+ free(reply);
+ } //end check for reply structure
+ } //end loop over active/inactive monitor state
} //end loading of active/enabled monitor information
-
- //Now load any information from the outputs
- for(int i=0; i<p_obj.outputs.length(); i++){
- xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
- xcb_randr_get_output_info_unchecked(QX11Info::connection(), p_obj.outputs[i], QX11Info::appTime()),
- NULL);
- if(info==0){ continue; } //bad output
- //Modes
- int mode_len = xcb_randr_get_output_info_modes_length(info);
- qDebug() << "Number of Modes:" << mode_len;
- if(mode_len<=0){ continue; } //skip this output - not a physical screen which can be used
- p_obj.resolutions.clear();
- for(int j=0; j<mode_len; j++){
- xcb_randr_mode_t mode = xcb_randr_get_output_info_modes(info)[j];
- //Still need to convert the mode into the resolution somehow
- p_obj.resolutions << QSize(mode,1);
- }
- }
}
@@ -203,29 +257,47 @@ void OutputDevice::updateInfoCache(){
// ============================
OutputDeviceList::OutputDeviceList(){
-
- QList<xcb_randr_output_t> usedOutputs;
+ xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(QX11Info::connection(),
+ xcb_randr_get_screen_resources_unchecked(QX11Info::connection(), QX11Info::appRootWindow()),
+ NULL);
+ int outputnum = xcb_randr_get_screen_resources_outputs_length(reply);
+ for(int i=0; i<outputnum; i++){
+ xcb_randr_output_t output = xcb_randr_get_screen_resources_outputs(reply)[i];
+ //Now display the info about this output
+ xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
+ xcb_randr_get_output_info_unchecked(QX11Info::connection(), output, QX11Info::appTime()),
+ NULL);
+ //Name
+ QString name = QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info));
+ OutputDevice dev(name);
+ out_devs.append(dev); //add to the internal list
+ }
+ //QList<xcb_atom_t> usedOutputs;
//Get the information about all the "enabled" monitors
- xcb_randr_get_monitors_cookie_t cookieA = xcb_randr_get_monitors_unchecked(QX11Info::connection(), QX11Info::appRootWindow(), 1);
- xcb_randr_get_monitors_reply_t *replyA = xcb_randr_get_monitors_reply(QX11Info::connection(), cookieA, NULL);
- if(replyA!=0){
- xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator(replyA);
- //qDebug() << "Number of Monitors:" << xcb_randr_get_monitors_monitors_length(reply);
- while(iter.rem>0){
- //qDebug() << "Found Monitor:";
- //qDebug() << " Index:" << iter.index << "Rem:" << iter.rem;
- QString name = atomToName(iter.data->name);
- OutputDevice dev(name);
- usedOutputs << dev.p_obj.outputs;
-
- this->append(dev); //add to the internal list
- xcb_randr_monitor_info_next(&iter);
- }
- //Free up any objects we are done with
- free(replyA);
- } //end loading of active/enabled monitors
-
-/*
+ /*for(int i=0; i<2; i++){ //loop over active/inactive monitors
+ qDebug() << "Scanning For Monitors:" << (i==0 ? "active" : "inactive");
+ xcb_randr_get_monitors_cookie_t cookieA = xcb_randr_get_monitors_unchecked(QX11Info::connection(), QX11Info::appRootWindow(), (i==0 ? 1 : 10)); //toggle active/inactive monitors
+ xcb_randr_get_monitors_reply_t *replyA = xcb_randr_get_monitors_reply(QX11Info::connection(), cookieA, NULL);
+ if(replyA!=0){
+ xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator(replyA);
+ qDebug() << "Number of Monitors:" << xcb_randr_get_monitors_monitors_length(replyA);
+ while(iter.rem>0){
+ //qDebug() << "Found Monitor:";
+ //qDebug() << " Index:" << iter.index << "Rem:" << iter.rem;
+ if(!usedOutputs.contains(iter.data->name)){
+ QString name = atomToName(iter.data->name);
+ OutputDevice dev(name);
+ usedOutputs << iter.data->name;
+ out_devs.append(dev); //add to the internal list
+ }
+ xcb_randr_monitor_info_next(&iter);
+ }
+ //Free up any objects we are done with
+ free(replyA);
+ } //end loading of active/enabled monitors
+ } //end loop over active/inactive monitors
+ */
+ qDebug() << "=========================";
//Now get the information about any **UNUSED** monitors/outputs
xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(QX11Info::connection(),
xcb_randr_get_screen_resources_unchecked(QX11Info::connection(), QX11Info::appRootWindow()),
@@ -233,21 +305,24 @@ OutputDeviceList::OutputDeviceList(){
int outputnum = xcb_randr_get_screen_resources_outputs_length(reply);
qDebug() << "Probing Screen Resources:";
qDebug() << " - Number of Outputs:" << outputnum;
- qDebug() << " - Number of CRTC's:" << xcb_randr_get_screen_resources_crtcs_length(reply);
- int mode_len =xcb_randr_get_screen_resources_modes_length(reply);
- qDebug() << " - Modes:" << mode_len;
- for(int m=0; m<mode_len; m++){
+ //qDebug() << " - Number of CRTC's:" << xcb_randr_get_screen_resources_crtcs_length(reply);
+ //int mode_len =xcb_randr_get_screen_resources_modes_length(reply);
+ //qDebug() << " - Modes:" << mode_len;
+ /*for(int m=0; m<mode_len; m++){
xcb_randr_mode_info_t mode = xcb_randr_get_screen_resources_modes(reply)[m];
//qDebug() << " -- Mode:" << mode.id;
qDebug() << " - Size Option:" << mode.width <<"x"<<mode.height;
- }
+ }*/
for(int i=0; i<outputnum; i++){
xcb_randr_output_t output = xcb_randr_get_screen_resources_outputs(reply)[i];
//Now display the info about this output
- xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
+ xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(QX11Info::connection(),
xcb_randr_get_output_info_unchecked(QX11Info::connection(), output, QX11Info::appTime()),
NULL);
qDebug() << "==== Output Information #"+QString::number(i);
+ //Name
+ int name_len = xcb_randr_get_output_info_name_length(info);
+ qDebug() << "Name:" << QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), name_len);
//Modes
int mode_len = xcb_randr_get_output_info_modes_length(info);
@@ -255,19 +330,11 @@ OutputDeviceList::OutputDeviceList(){
if(mode_len<=0){ continue; } //skip this output - not a physical screen which can be used
- //Clones
+ //Clones
qDebug() << "Number of Clones:" << xcb_randr_get_output_info_clones_length(info);
- //Names
- int name_len = xcb_randr_get_output_info_name_length(info);
- qDebug() << "Names:"; //<< atomsToNames( (xcb_atom_t*) xcb_randr_get_output_info_name(info), name_len);
- for(int n=0; n<name_len; n++){
- QString name = atomToName( xcb_randr_get_output_info_name(info)[n] );
- qDebug() << " -- " << name;
- }
-
//Properties
- xcb_randr_list_output_properties_reply_t *pinfo = xcb_randr_list_output_properties_reply(QX11Info::connection(),
+ /* xcb_randr_list_output_properties_reply_t *pinfo = xcb_randr_list_output_properties_reply(QX11Info::connection(),
xcb_randr_list_output_properties_unchecked(QX11Info::connection(), output),
NULL);
int pinfo_len = xcb_randr_list_output_properties_atoms_length(pinfo);
@@ -286,11 +353,11 @@ OutputDeviceList::OutputDeviceList(){
}
free(pinfo);
-
+ */
free(info);
}
-
- free(reply);*/
+
+ free(reply);
}
OutputDeviceList::~OutputDeviceList(){
@@ -303,5 +370,11 @@ void OutputDeviceList::setPrimaryMonitor(QString id){
}
void OutputDeviceList::disableMonitor(QString id){
-
+ for(int i=0; i<out_devs.length(); i++){
+ if(out_devs[i].ID() == id){
+ out_devs[i].disable();
+ out_devs[i].updateInfoCache();
+ break;
+ }
+ }
}
bgstack15