aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-qt5/core/libLumina/LuminaRandR-X11.cpp88
-rw-r--r--src-qt5/core/libLumina/LuminaRandR.h3
2 files changed, 65 insertions, 26 deletions
diff --git a/src-qt5/core/libLumina/LuminaRandR-X11.cpp b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
index 2e42aa48..4c1d5de3 100644
--- a/src-qt5/core/libLumina/LuminaRandR-X11.cpp
+++ b/src-qt5/core/libLumina/LuminaRandR-X11.cpp
@@ -33,6 +33,14 @@ inline QStringList atomsToNames(xcb_atom_t *atoms, unsigned int num){
};
inline bool loadScreenInfo(p_objects *p_obj){
+ //Reset the primary cached values (just in case things error out below and it can't finish)
+ p_obj->current_mode = 0;
+ p_obj->geometry = QRect();
+ p_obj->physicalSizeMM = QSize();
+ p_obj->primary = false;
+ p_obj->modes.clear();
+ p_obj->resolutions.clear();
+
//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()),
@@ -44,16 +52,15 @@ inline bool loadScreenInfo(p_objects *p_obj){
//Modes
int mode_len = xcb_randr_get_output_info_modes_length(info);
- p_obj->modes.clear();
for(int j=0; j<mode_len; j++){
p_obj->modes.append( xcb_randr_get_output_info_modes(info)[j] );
}
- xcb_randr_crtc_t crtc = info->crtc;
+ p_obj->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()),
+ xcb_randr_get_crtc_info_unchecked(QX11Info::connection(), p_obj->crtc, QX11Info::appTime()),
NULL);
if(cinfo==0){ return false; }
p_obj->geometry = QRect(cinfo->x, cinfo->y, cinfo->width, cinfo->height);
@@ -61,38 +68,57 @@ inline bool loadScreenInfo(p_objects *p_obj){
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(),
+ if(!p_obj->modes.isEmpty()){
+ //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;
+ if(preply !=0){
+ p_obj->primary = (preply->output == p_obj->output);
+ free(preply);
+ }
+
+ //Now load all the screen resources information, and find matches for the current modes
+ 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);
+ }
}
- //Now load all the screen resources information, and find matches for the current modes
- p_obj->resolutions.clear();
+ return true;
+}
+
+
+inline xcb_randr_mode_t modeForResolution(QSize res, QList<xcb_randr_mode_t> modes){
+ xcb_randr_mode_t det_mode = XCB_NONE;
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){
+ unsigned int refreshrate = 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)){
+ if(modes.contains(minfo.id)){
QSize sz(minfo.width, minfo.height);
- if(!p_obj->resolutions.contains(sz)){ p_obj->resolutions.append( sz); }
+ if(sz == res && minfo.dot_clock > refreshrate){ det_mode = minfo.id; refreshrate = minfo.dot_clock; }
}
}
free(srreply);
}
- return true;
+ return det_mode;
}
/*
//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_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);
@@ -155,22 +181,34 @@ bool OutputDevice::setAsPrimary(bool set){
}
bool OutputDevice::disable(){
- if(p_obj.output!=0 && p_obj.current_mode!=0){
+ if(p_obj.output!=0 && p_obj.current_mode!=0 && p_obj.crtc!=0){
//qDebug() << " - Go ahead";
- //XLib version
- //XRRDeleteOutputMode(QX11Info::display(), p_obj.output, p_obj.current_mode);
- //XCB version
- xcb_randr_delete_output_mode(QX11Info::connection(), p_obj.output, p_obj.current_mode);
- return true;
+ 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, 0, 0, XCB_NONE, XCB_RANDR_ROTATION_ROTATE_0, 0, NULL);
+ //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; }
+ bool ok = (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS);
+ free(reply);
+ return ok;
}
return false;
}
-void OutputDevice::enable(QRect geom){
+bool OutputDevice::enable(QRect geom){
//if no geom provided, will add as the right-most screen at optimal resolution
- if(this->isEnabled()){ return; } //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
+ 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);
+ //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; }
+ bool ok = (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS);
+ free(reply);
+ return ok;
}
void OutputDevice::changeResolution(QSize){
diff --git a/src-qt5/core/libLumina/LuminaRandR.h b/src-qt5/core/libLumina/LuminaRandR.h
index 6175a9d0..0e806ba5 100644
--- a/src-qt5/core/libLumina/LuminaRandR.h
+++ b/src-qt5/core/libLumina/LuminaRandR.h
@@ -26,6 +26,7 @@
struct p_objects{
xcb_randr_output_t output; //This is the index used to identify particular monitors (unique ID)
+ xcb_randr_crtc_t crtc; //This is the index used for the current settings/configuration (associated with output)
//Cached Information
bool primary;
@@ -73,7 +74,7 @@ public:
//Modification
bool setAsPrimary(bool);
bool disable();
- void enable(QRect geom = QRect()); //if no geom provided, will add as the right-most screen at optimal resolution
+ bool enable(QRect geom = QRect()); //if no geom provided, will add as the right-most screen at optimal resolution
void changeResolution(QSize);
void changeGeometry(QRect); //move a currently-enabled screen to another place
bgstack15