aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina/LuminaRandR-X11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core/libLumina/LuminaRandR-X11.cpp')
-rw-r--r--src-qt5/core/libLumina/LuminaRandR-X11.cpp312
1 files changed, 89 insertions, 223 deletions
diff --git a/src-qt5/core/libLumina/LuminaRandR-X11.cpp b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
index 0e68cfd2..2e42aa48 100644
--- a/src-qt5/core/libLumina/LuminaRandR-X11.cpp
+++ b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
@@ -32,36 +32,46 @@ 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(),
+inline bool loadScreenInfo(p_objects *p_obj){
+ //Get the information associated with the output and save it in the p_objects cache
+ 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
+ if(info==0){ return false; } //bad output value
+ //First read off the information associated with the output itself
+ if(p_obj->name.isEmpty()){ p_obj->name = QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info)); }
+ p_obj->physicalSizeMM = QSize(info->mm_width, info->mm_height);
+
//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;
+ xcb_randr_crtc_t crtc = info->crtc;
+ free(info); //done with output_info
+
+ //Now load the current status of the output (crtc information)
+ xcb_randr_get_crtc_info_reply_t *cinfo = xcb_randr_get_crtc_info_reply(QX11Info::connection(),
+ xcb_randr_get_crtc_info_unchecked(QX11Info::connection(), crtc, QX11Info::appTime()),
+ NULL);
+ if(cinfo==0){ return false; }
+ p_obj->geometry = QRect(cinfo->x, cinfo->y, cinfo->width, cinfo->height);
+ p_obj->current_mode = cinfo->mode;
+
+ free(cinfo); //done with crtc_info
+
+ //And see if this output is currently the primary output
+ xcb_randr_get_output_primary_reply_t *preply = xcb_randr_get_output_primary_reply(QX11Info::connection(),
+ xcb_randr_get_output_primary_unchecked(QX11Info::connection(), QX11Info::appRootWindow()), NULL);
+
+ if(preply !=0){
+ p_obj->primary = (preply->output == p_obj->output);
+ free(preply);
+ }else{
+ p_obj->primary = false;
+ }
+ //Now load all the screen resources information, and find matches for the current 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);
@@ -78,68 +88,35 @@ inline bool loadScreenInfo(p_objects *p_obj, xcb_randr_monitor_info_t *info){
return true;
}
-/*class OutputDevice::p_objects{
-public:
- xcb_atom_t monitor_atom; //This is the index used to identify particular monitors (unique ID)
-
- //Cached Information
- bool primary, automatic;
- QRect geometry;
- QList<QSize> resolutions;
- QSize physicalSizeMM;
- QString name;
- QList<xcb_randr_output_t> outputs;
-
- p_objects(){
- // Set the defaults for non-default-constructed variables
- primary = automatic = false;
- monitor_atom = 0;
- }
-
-};*/
-
-//Global Listing of Devices
-QList<OutputDevice> OutputDevice::availableMonitors(){
- QList<OutputDevice> list;
- //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){
- qDebug() << "Could not get monitor list";
- return list;
- }
- 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() << "Found Monitor:";
- //qDebug() << " Index:" << iter.index << "Rem:" << iter.rem;
- QString name = atomToName(iter.data->name);
- /*xcb_get_atom_name_reply_t *nreply = xcb_get_atom_name_reply(QX11Info::connection(), xcb_get_atom_name_unchecked(QX11Info::connection(), iter.data->name), NULL);
- QString name = QString::fromLocal8Bit(xcb_get_atom_name_name(nreply), xcb_get_atom_name_name_length(nreply));
- free(nreply);*/
-
- qDebug() << " - Name:" << iter.data->name << name;
- qDebug() << " - Primary:" << (iter.data->primary == 1);
- qDebug() << " - Automatic:" << (iter.data->automatic == 1);
- qDebug() << " - nOutput:" << iter.data->nOutput;
- qDebug() << " - Geometry:" << QRect(iter.data->x, iter.data->y, iter.data->width, iter.data->height);
- qDebug() << " - Physical Size (mm):" << iter.data->width_in_millimeters << "x" << iter.data->height_in_millimeters;
- qDebug() << " - Number of outputs:" << xcb_randr_monitor_info_outputs_length(iter.data);
- xcb_randr_monitor_info_next(&iter);
- }
+/*
+ //Clones
+ qDebug() << "Number of Clones:" << xcb_randr_get_output_info_clones_length(info);
+ //Properties
+ /* 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);
+ qDebug() << "Properties:" << pinfo_len;
+ for(int p=0; p<pinfo_len; p++){
+ xcb_atom_t atom = xcb_randr_list_output_properties_atoms(pinfo)[p];
+ //Property Name
+ QString name = atomToName(atom);
+ //Property Value
+ xcb_randr_query_output_property_reply_t *pvalue = xcb_randr_query_output_property_reply(QX11Info::connection(),
+ xcb_randr_query_output_property_unchecked(QX11Info::connection(), output, atom),
+ NULL);
+ QStringList values = atomsToNames ( (xcb_atom_t*) xcb_randr_query_output_property_valid_values(pvalue), xcb_randr_query_output_property_valid_values_length(pvalue) ); //need to read values
+ free(pvalue);
+ qDebug() << " -- " << name << "=" << values;
- //Free up any objects we are done with
- free(reply);
- //Return the list
- return list;
-}
+ }
+*/
-//FUNCTIONS (do not use directly - use the static list function instead)
+//FUNCTIONS (do not use typically use manually - use the OutputDeviceList class instead)
OutputDevice::OutputDevice(QString id){
//p_obj = new p_objects();
p_obj.name = id;
- p_obj.primary = p_obj.automatic = false;
- p_obj.monitor_atom = 0;
+ p_obj.primary = false;
p_obj.output = 0;
bool ok = false;
p_obj.output = id.toInt(&ok);
@@ -158,43 +135,32 @@ OutputDevice::~OutputDevice(){
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; }
+QSize OutputDevice::physicalDPI(){
+ QSize dpi( qRound((p_obj.geometry.width() * 25.4)/p_obj.physicalSizeMM.width()), qRound((p_obj.geometry.height() * 25.4)/p_obj.physicalSizeMM.height() ) );
+ return dpi;
+}
//Modification
bool OutputDevice::setAsPrimary(bool set){
if(p_obj.primary == set){ return true; } //no change needed
- bool ok = false;
- for(int i=0; i<p_obj.outputs.length(); i++){
- if(set){ xcb_randr_set_output_primary (QX11Info::connection(), QX11Info::appRootWindow(), p_obj.outputs[i]); }
+ if(set){ xcb_randr_set_output_primary (QX11Info::connection(), QX11Info::appRootWindow(), p_obj.output); }
p_obj.primary = set; //Only need to push a "set" primary up through XCB - will automatically deactivate the other monitors
- ok = true;
- break;
- }
- return ok;
+ return true;
}
bool OutputDevice::disable(){
- //qDebug() << "Disable Monitor:" << p_obj.monitor_atom;
- if(p_obj.monitor_atom!=0){
+ if(p_obj.output!=0 && p_obj.current_mode!=0){
//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]);
+ //XRRDeleteOutputMode(QX11Info::display(), p_obj.output, p_obj.current_mode);
//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;
+ xcb_randr_delete_output_mode(QX11Info::connection(), p_obj.output, p_obj.current_mode);
return true;
}
return false;
@@ -202,7 +168,7 @@ bool OutputDevice::disable(){
void OutputDevice::enable(QRect geom){
//if no geom provided, will add as the right-most screen at optimal resolution
- if(p_obj.monitor_atom!=0){ return; }
+ if(this->isEnabled()){ return; } //already enabled
qDebug() << "Enable Monitor:" << geom;
}
@@ -212,44 +178,25 @@ void OutputDevice::changeResolution(QSize){
}
void OutputDevice::updateInfoCache(){
- xcb_randr_get_screen_resources_reply_t *reply = xcb_randr_get_screen_resources_reply(QX11Info::connection(),
+ if(p_obj.output==0){
+ //Only have a name (first run) - need to find the corresponding output for this ID
+ 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)
+ 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];
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
+ //Compare names
QString name = QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info));
- if(
+ if(name == p_obj.name){ p_obj.output = output; break; }
+ }
+ free(reply);
}
-
- //Find the **active** monitor with the given id/name
- if(p_obj.monitor_atom !=0 || !p_obj.name.isEmpty() ){
- 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);
- }
- free(reply);
- } //end check for reply structure
- } //end loop over active/inactive monitor state
- } //end loading of active/enabled monitor information
-
+ if(p_obj.output == 0){ return; } //bad ID/output?
+ loadScreenInfo(&p_obj);
}
// ============================
@@ -260,103 +207,13 @@ OutputDeviceList::OutputDeviceList(){
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);
+ if(reply==0){ return; } //could not get screen information
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);
+ OutputDevice dev(QString::number(output)); //use the raw output integer
out_devs.append(dev); //add to the internal list
}
- //QList<xcb_atom_t> usedOutputs;
- //Get the information about all the "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()),
- NULL);
- 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++){
- 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_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);
- qDebug() << "Number of Modes:" << mode_len;
- if(mode_len<=0){ continue; } //skip this output - not a physical screen which can be used
-
-
- //Clones
- qDebug() << "Number of Clones:" << xcb_randr_get_output_info_clones_length(info);
-
- //Properties
- /* 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);
- qDebug() << "Properties:" << pinfo_len;
- for(int p=0; p<pinfo_len; p++){
- xcb_atom_t atom = xcb_randr_list_output_properties_atoms(pinfo)[p];
- //Property Name
- QString name = atomToName(atom);
- //Property Value
- xcb_randr_query_output_property_reply_t *pvalue = xcb_randr_query_output_property_reply(QX11Info::connection(),
- xcb_randr_query_output_property_unchecked(QX11Info::connection(), output, atom),
- NULL);
- QStringList values = atomsToNames ( (xcb_atom_t*) xcb_randr_query_output_property_valid_values(pvalue), xcb_randr_query_output_property_valid_values_length(pvalue) ); //need to read values
- free(pvalue);
- qDebug() << " -- " << name << "=" << values;
-
- }
- free(pinfo);
- */
- free(info);
- }
-
free(reply);
}
@@ -366,7 +223,16 @@ OutputDeviceList::~OutputDeviceList(){
//Simplification functions for dealing with multiple monitors
void OutputDeviceList::setPrimaryMonitor(QString id){
+ for(int i=0; i<out_devs.length(); i++){
+ out_devs[i].setAsPrimary(out_devs[i].ID() == id);
+ }
+}
+QString OutputDeviceList::primaryMonitor(){
+ for(int i=0; i<out_devs.length(); i++){
+ if(out_devs[i].isPrimary()){ return out_devs[i].ID(); }
+ }
+ return "";
}
void OutputDeviceList::disableMonitor(QString id){
bgstack15