Switch monitors based on keyboard shortcuts

This commit is contained in:
loki
2021-07-29 16:48:03 +02:00
parent c243e82047
commit 2af179630a
6 changed files with 136 additions and 21 deletions
+12 -1
View File
@@ -271,7 +271,18 @@ std::string from_sockaddr(const sockaddr *const);
std::pair<std::uint16_t, std::string> from_sockaddr_ex(const sockaddr *const);
std::unique_ptr<audio_control_t> audio_control();
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, int framerate);
/**
* display_name --> The name of the monitor that SHOULD be displayed
* If display_name is empty --> Use the first monitor that's compatible you can find
* If you require to use this parameter in a seperate thread --> make a copy of it.
*
* framerate --> The peak number of images per second
*
* Returns display_t based on hwdevice_type
*/
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, int framerate);
std::vector<std::string> display_names();
input_t input();
void move_mouse(input_t &input, int deltaX, int deltaY);
+39 -8
View File
@@ -155,7 +155,7 @@ struct x11_attr_t : public display_t {
XInitThreads();
}
int init(int framerate) {
int init(int framerate, const std::string &output_name) {
if(!xdisplay) {
BOOST_LOG(error) << "Could not open X11 display"sv;
return -1;
@@ -168,8 +168,8 @@ struct x11_attr_t : public display_t {
refresh();
int streamedMonitor = -1;
if(!config::video.output_name.empty()) {
streamedMonitor = (int)util::from_view(config::video.output_name);
if(!output_name.empty()) {
streamedMonitor = (int)util::from_view(output_name);
}
if(streamedMonitor != -1) {
@@ -399,8 +399,8 @@ struct shm_attr_t : public x11_attr_t {
return 0;
}
int init(int framerate) {
if(x11_attr_t::init(framerate)) {
int init(int framerate, const std::string &output_name) {
if(x11_attr_t::init(framerate, output_name)) {
return 1;
}
@@ -443,7 +443,7 @@ struct shm_attr_t : public x11_attr_t {
}
};
std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, int framerate) {
std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, const std::string &output_name, int framerate) {
if(hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) {
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
return nullptr;
@@ -452,7 +452,7 @@ std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, int framerat
// Attempt to use shared memory X11 to avoid copying the frame
auto shm_disp = std::make_shared<shm_attr_t>(hwdevice_type);
auto status = shm_disp->init(framerate);
auto status = shm_disp->init(framerate, output_name);
if(status > 0) {
// x11_attr_t::init() failed, don't bother trying again.
return nullptr;
@@ -464,13 +464,44 @@ std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type, int framerat
// Fallback
auto x11_disp = std::make_shared<x11_attr_t>(hwdevice_type);
if(x11_disp->init(framerate)) {
if(x11_disp->init(framerate, output_name)) {
return nullptr;
}
return x11_disp;
}
std::vector<std::string> display_names() {
BOOST_LOG(info) << "Detecting connected monitors"sv;
xdisplay_t xdisplay { XOpenDisplay(nullptr) };
if(!xdisplay) {
return {};
}
auto xwindow = DefaultRootWindow(xdisplay.get());
screen_res_t screenr { XRRGetScreenResources(xdisplay.get(), xwindow) };
int output = screenr->noutput;
int monitor = 0;
for(int x = 0; x < output; ++x) {
output_info_t out_info { XRRGetOutputInfo(xdisplay.get(), screenr.get(), screenr->outputs[x]) };
if(out_info && out_info->connection == RR_Connected) {
++monitor;
}
}
std::vector<std::string> names;
names.reserve(monitor);
for(auto x = 0; x < monitor; ++x) {
BOOST_LOG(fatal) << x;
names.emplace_back(std::to_string(x));
}
return names;
}
void freeImage(XImage *p) {
XDestroyImage(p);
}