//=========================================== // Lumina-DE source code // Copyright (c) 2017, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "LuminaRandR.h" //#include "xcb/randr.h" //#include "xcb/xcb_atom.h" #include #include 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); QString name = QString::fromLocal8Bit(xcb_get_atom_name_name(nreply), xcb_get_atom_name_name_length(nreply)); free(nreply); return name; }; //More efficient method for converting lots of atoms to strings inline QStringList atomsToNames(xcb_atom_t *atoms, unsigned int num){ //qDebug() << "atomsToNames:" << num; QList< xcb_get_atom_name_cookie_t > cookies; //qDebug() << " - Get cookies"; for(unsigned int i=0; i resolutions; QSize physicalSizeMM; QString name; QList outputs; p_objects(){ // Set the defaults for non-default-constructed variables primary = automatic = false; monitor_atom = 0; } };*/ //Global Listing of Devices QList OutputDevice::availableMonitors(){ QList 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); } //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) 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; updateInfoCache(); } OutputDevice::~OutputDevice(){ //delete p_obj; } // 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; } bool OutputDevice::isPrimary(){ return p_obj.primary; } bool OutputDevice::isAutomatic(){ return p_obj.automatic; } QList 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; } //Modification bool OutputDevice::setAsPrimary(bool set){ if(p_obj.primary == set){ return true; } //no change needed bool ok = false; for(int i=0; i0){ //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 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 /* //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