aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina
diff options
context:
space:
mode:
authorKen Moore <ken@ixsystems.com>2017-06-22 13:50:48 -0400
committerKen Moore <ken@ixsystems.com>2017-06-22 13:50:48 -0400
commit1ea2ff8cf7f9a012fafc4b910e940aa5627ccaa6 (patch)
tree5207612b56b0c0b28a26b858cd2ceac64bc750f1 /src-qt5/core/libLumina
parentMerge branch 'master' of github.com:trueos/lumina (diff)
downloadlumina-1ea2ff8cf7f9a012fafc4b910e940aa5627ccaa6.tar.gz
lumina-1ea2ff8cf7f9a012fafc4b910e940aa5627ccaa6.tar.bz2
lumina-1ea2ff8cf7f9a012fafc4b910e940aa5627ccaa6.zip
Get the LuminaRandR framework able to enable/resize/move a monitor as requested.
NOTE: The automatic resolution routine picks the larges one available for the monitor, but some monitors lie and don't actually support all the listed resolutions (probably because I am using an HDMI->VGA converter on my Laptop output right now).
Diffstat (limited to 'src-qt5/core/libLumina')
-rw-r--r--src-qt5/core/libLumina/LuminaRandR-X11.cpp67
-rw-r--r--src-qt5/core/libLumina/LuminaRandR.h4
-rw-r--r--src-qt5/core/libLumina/test/main.cpp19
3 files changed, 79 insertions, 11 deletions
diff --git a/src-qt5/core/libLumina/LuminaRandR-X11.cpp b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
index a78821db..8fcdbad0 100644
--- a/src-qt5/core/libLumina/LuminaRandR-X11.cpp
+++ b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
@@ -40,6 +40,7 @@ inline bool loadScreenInfo(p_objects *p_obj){
p_obj->primary = false;
p_obj->modes.clear();
p_obj->resolutions.clear();
+ p_obj->crtc = 0;
//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(),
@@ -55,6 +56,11 @@ inline bool loadScreenInfo(p_objects *p_obj){
for(int j=0; j<mode_len; j++){
p_obj->modes.append( xcb_randr_get_output_info_modes(info)[j] );
}
+ //int pref_len = info->num_preferred;
+ //qDebug() << "Modes:" << p_obj->modes << "Num Preferred:" << pref_len;
+ /*for(int j=0; j<pref_len; j++){
+ p_obj->preferred.append( xcb_randr_get_output_info_preferred(info)[j] );
+ }*/
p_obj->crtc = info->crtc;
free(info); //done with output_info
@@ -102,11 +108,19 @@ inline xcb_randr_mode_t modeForResolution(QSize res, QList<xcb_randr_mode_t> mod
xcb_randr_get_screen_resources_unchecked(QX11Info::connection(), QX11Info::appRootWindow()), NULL);
if(srreply!=0){
unsigned int refreshrate = 0;
+ QSize sz;
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(modes.contains(minfo.id)){
- QSize sz(minfo.width, minfo.height);
- if(sz == res && minfo.dot_clock > refreshrate){ det_mode = minfo.id; refreshrate = minfo.dot_clock; }
+ if(res.isNull() && (minfo.width > sz.width() || minfo.height > sz.height()) ){
+ //No resolution requested - pick the largest one
+ qDebug() << "Found Bigger Mode:" << sz << QSize(minfo.width, minfo.height);
+ sz = QSize(minfo.width, minfo.height);
+ det_mode = minfo.id;
+ }else if(!res.isNull()){
+ sz = QSize(minfo.width, minfo.height);
+ if(sz == res && minfo.dot_clock > refreshrate){ det_mode = minfo.id; refreshrate = minfo.dot_clock; }
+ }
}
}
free(srreply);
@@ -197,12 +211,38 @@ bool OutputDevice::disable(){
bool OutputDevice::enable(QRect geom){
//if no geom provided, will add as the right-most screen at optimal resolution
- if(this->isEnabled()){ return true; } //already enabled
+ //if(this->isEnabled()){ return true; } //already enabled
qDebug() << "Enable Monitor:" << geom;
xcb_randr_mode_t mode = modeForResolution(geom.size(), p_obj.modes);
if(mode==XCB_NONE){ return false; } //invalid resolution for this monitor
+ //qDebug() << " - Found Mode:" << mode;
+ if(p_obj.crtc == 0){
+ //Need to scan for an available crtc to use (turning on a monitor for the first time)
+ 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 num = xcb_randr_get_screen_resources_crtcs_length(reply);
+ for(int i=0; i<num && p_obj.crtc==0; i++){
+ xcb_randr_crtc_t crt = xcb_randr_get_screen_resources_crtcs(reply)[i];
+ xcb_randr_get_crtc_info_reply_t *info = xcb_randr_get_crtc_info_reply(QX11Info::connection(),
+ xcb_randr_get_crtc_info_unchecked(QX11Info::connection(), crt, QX11Info::appTime()),
+ NULL);
+ //Verify that the output is supported by this crtc
+ QList<xcb_randr_output_t> possible;
+ if(xcb_randr_get_crtc_info_outputs_length(info) < 1){ //make sure it is not already associated with an output
+ int pnum = xcb_randr_get_crtc_info_possible_length(info);
+ for(int p=0; p<pnum; p++){ possible << xcb_randr_get_crtc_info_possible(info)[p]; }
+ }
+ if(possible.contains(p_obj.output)){ p_obj.crtc = crt; }
+ free(info);
+ }
+ free(reply);
+ }
+ //qDebug() << " - Using crtc:" << p_obj.crtc;
+ xcb_randr_output_t outList[1]{ p_obj.output };
+
xcb_randr_set_crtc_config_cookie_t cookie = xcb_randr_set_crtc_config_unchecked(QX11Info::connection(), p_obj.crtc,
- XCB_CURRENT_TIME, XCB_CURRENT_TIME, geom.x(), geom.y(), mode, XCB_RANDR_ROTATION_ROTATE_0, 1, &p_obj.output);
+ XCB_CURRENT_TIME, XCB_CURRENT_TIME, geom.x(), geom.y(), mode, XCB_RANDR_ROTATION_ROTATE_0, 1, outList);
//Now check the result of the configuration
xcb_randr_set_crtc_config_reply_t *reply = xcb_randr_set_crtc_config_reply(QX11Info::connection(), cookie, NULL);
if(reply==0){ return false; }
@@ -229,6 +269,7 @@ void OutputDevice::updateInfoCache(){
NULL);
//Compare names
QString name = QString::fromLocal8Bit( (char*) xcb_randr_get_output_info_name(info), xcb_randr_get_output_info_name_length(info));
+ free(info);
if(name == p_obj.name){ p_obj.output = output; break; }
}
free(reply);
@@ -273,12 +314,26 @@ QString OutputDeviceList::primaryMonitor(){
return "";
}
-void OutputDeviceList::disableMonitor(QString id){
+bool OutputDeviceList::disableMonitor(QString id){
+ bool ok = false;
+ for(int i=0; i<out_devs.length(); i++){
+ if(out_devs[i].ID() == id){
+ ok = out_devs[i].disable();
+ out_devs[i].updateInfoCache();
+ break;
+ }
+ }
+ return ok;
+}
+
+bool OutputDeviceList::enableMonitor(QString id, QRect geom){
+ bool ok = false;
for(int i=0; i<out_devs.length(); i++){
if(out_devs[i].ID() == id){
- out_devs[i].disable();
+ ok = out_devs[i].enable(geom);
out_devs[i].updateInfoCache();
break;
}
}
+ return ok;
}
diff --git a/src-qt5/core/libLumina/LuminaRandR.h b/src-qt5/core/libLumina/LuminaRandR.h
index 0e806ba5..fa2db63e 100644
--- a/src-qt5/core/libLumina/LuminaRandR.h
+++ b/src-qt5/core/libLumina/LuminaRandR.h
@@ -105,8 +105,8 @@ public:
void setPrimaryMonitor(QString id);
QString primaryMonitor();
- void disableMonitor(QString id);
- //void enableMonitor(QString id, QRect geom);
+ bool disableMonitor(QString id);
+ bool enableMonitor(QString id, QRect geom);
};
#endif
diff --git a/src-qt5/core/libLumina/test/main.cpp b/src-qt5/core/libLumina/test/main.cpp
index 8f809b24..547a1846 100644
--- a/src-qt5/core/libLumina/test/main.cpp
+++ b/src-qt5/core/libLumina/test/main.cpp
@@ -5,9 +5,14 @@
int main(int argc, char** argv){
+ QString toggle = "HDMI-2";
+ QRect toggleGeom(1921,0, 1024,768); //put to the right of the default monitor
+ int toggleOK = -1; //-1: automatic, 0: enable monitor, 1: disable monitor
+
QApplication A(argc, argv);
qDebug() << "Load Monitor Device Information";
OutputDeviceList devList;
+
qDebug() << "Detected Information:";
for(int i=0; i<devList.length(); i++){
qDebug() << "["+devList.at(i)->ID()+"]";
@@ -19,11 +24,19 @@ int main(int argc, char** argv){
qDebug() << " - Physical Size (mm):" << devList.at(i)->physicalSizeMM();
qDebug() << " - Current DPI:" << devList.at(i)->physicalDPI();
qDebug() << " - Available Resolutions:" << devList.at(i)->availableResolutions();
+ if(devList.at(i)->ID() == toggle && toggleOK<0){ toggleOK = (devList.at(i)->isEnabled() ? 1 : 0); }
}
}
- /*QString disable = "HDMI-2";
- qDebug() << "Try Disabling Monitor:" << disable;
- devList.disableMonitor(disable);*/
+ qDebug() << "\n================\n";
+ if(toggleOK == 0){
+ qDebug() << "Try Enabling Monitor:" << toggle << toggleGeom;
+ bool ok = devList.enableMonitor(toggle, toggleGeom);
+ qDebug() << " -- Success:" << ok;
+ }else if(toggleOK == 1){
+ qDebug() << "Try Disabling Monitor:" << toggle;
+ bool ok = devList.disableMonitor(toggle);
+ qDebug() << " -- Success:" << ok;
+ }
/*QString setprimary = "eDP-1";
if(devList.primaryMonitor() != setprimary){
bgstack15