Switch monitors on Windows

This commit is contained in:
loki 2021-07-29 17:27:22 +02:00
parent 2af179630a
commit 6c11e9f27d
4 changed files with 70 additions and 9 deletions

View File

@ -282,6 +282,8 @@ std::unique_ptr<audio_control_t> audio_control();
* Returns display_t based on hwdevice_type * 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::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, int framerate);
// A list of names of displays accepted as display_name
std::vector<std::string> display_names(); std::vector<std::string> display_names();
input_t input(); input_t input();

View File

@ -74,7 +74,7 @@ public:
class display_base_t : public display_t { class display_base_t : public display_t {
public: public:
int init(int framerate); int init(int framerate, const std::string &display_name);
std::chrono::nanoseconds delay; std::chrono::nanoseconds delay;
@ -109,7 +109,7 @@ public:
std::shared_ptr<img_t> alloc_img() override; std::shared_ptr<img_t> alloc_img() override;
int dummy_img(img_t *img) override; int dummy_img(img_t *img) override;
int init(int framerate); int init(int framerate, const std::string &display_name);
cursor_t cursor; cursor_t cursor;
D3D11_MAPPED_SUBRESOURCE img_info; D3D11_MAPPED_SUBRESOURCE img_info;

View File

@ -73,7 +73,7 @@ duplication_t::~duplication_t() {
release_frame(); release_frame();
} }
int display_base_t::init(int framerate) { int display_base_t::init(int framerate, const std::string &display_name) {
/* Uncomment when use of IDXGIOutput5 is implemented /* Uncomment when use of IDXGIOutput5 is implemented
std::call_once(windows_cpp_once_flag, []() { std::call_once(windows_cpp_once_flag, []() {
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
@ -111,7 +111,7 @@ int display_base_t::init(int framerate) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
auto adapter_name = converter.from_bytes(config::video.adapter_name); auto adapter_name = converter.from_bytes(config::video.adapter_name);
auto output_name = converter.from_bytes(config::video.output_name); auto output_name = converter.from_bytes(display_name);
adapter_t::pointer adapter_p; adapter_t::pointer adapter_p;
for(int x = 0; factory->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) { for(int x = 0; factory->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) {
@ -433,22 +433,81 @@ const char *format_str[] = {
} // namespace platf::dxgi } // namespace platf::dxgi
namespace platf { namespace platf {
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, int framerate) { std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, int framerate) {
if(hwdevice_type == mem_type_e::dxgi) { if(hwdevice_type == mem_type_e::dxgi) {
auto disp = std::make_shared<dxgi::display_vram_t>(); auto disp = std::make_shared<dxgi::display_vram_t>();
if(!disp->init(framerate)) { if(!disp->init(framerate, display_name)) {
return disp; return disp;
} }
} }
else if(hwdevice_type == mem_type_e::system) { else if(hwdevice_type == mem_type_e::system) {
auto disp = std::make_shared<dxgi::display_ram_t>(); auto disp = std::make_shared<dxgi::display_ram_t>();
if(!disp->init(framerate)) { if(!disp->init(framerate, display_name)) {
return disp; return disp;
} }
} }
return nullptr; return nullptr;
} }
std::vector<std::string> display_names() {
std::vector<std::string> display_names;
HRESULT status;
BOOST_LOG(debug) << "Detecting monitors..."sv;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
dxgi::factory1_t factory;
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void **)&factory);
if(FAILED(status)) {
BOOST_LOG(error) << "Failed to create DXGIFactory1 [0x"sv << util::hex(status).to_string_view() << ']' << std::endl;
return {};
}
dxgi::adapter_t adapter;
for(int x = 0; factory->EnumAdapters1(x, &adapter) != DXGI_ERROR_NOT_FOUND; ++x) {
DXGI_ADAPTER_DESC1 adapter_desc;
adapter->GetDesc1(&adapter_desc);
BOOST_LOG(debug)
<< std::endl
<< "====== ADAPTER ====="sv << std::endl
<< "Device Name : "sv << converter.to_bytes(adapter_desc.Description) << std::endl
<< "Device Vendor ID : 0x"sv << util::hex(adapter_desc.VendorId).to_string_view() << std::endl
<< "Device Device ID : 0x"sv << util::hex(adapter_desc.DeviceId).to_string_view() << std::endl
<< "Device Video Mem : "sv << adapter_desc.DedicatedVideoMemory / 1048576 << " MiB"sv << std::endl
<< "Device Sys Mem : "sv << adapter_desc.DedicatedSystemMemory / 1048576 << " MiB"sv << std::endl
<< "Share Sys Mem : "sv << adapter_desc.SharedSystemMemory / 1048576 << " MiB"sv << std::endl
<< std::endl
<< " ====== OUTPUT ======"sv << std::endl;
dxgi::output_t::pointer output_p {};
for(int y = 0; adapter->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) {
dxgi::output_t output { output_p };
DXGI_OUTPUT_DESC desc;
output->GetDesc(&desc);
auto device_name = converter.to_bytes(desc.DeviceName);
auto width = desc.DesktopCoordinates.right - desc.DesktopCoordinates.left;
auto height = desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top;
BOOST_LOG(debug)
<< " Output Name : "sv << device_name << std::endl
<< " AttachedToDesktop : "sv << (desc.AttachedToDesktop ? "yes"sv : "no"sv) << std::endl
<< " Resolution : "sv << width << 'x' << height << std::endl
<< std::endl;
display_names.emplace_back(std::move(device_name));
}
}
return display_names;
}
} // namespace platf } // namespace platf

View File

@ -293,8 +293,8 @@ int display_ram_t::dummy_img(platf::img_t *img) {
return 0; return 0;
} }
int display_ram_t::init(int framerate) { int display_ram_t::init(int framerate, const std::string &display_name) {
if(display_base_t::init(framerate)) { if(display_base_t::init(framerate, display_name)) {
return -1; return -1;
} }