diff --git a/libobs-winrt/winrt-capture.cpp b/libobs-winrt/winrt-capture.cpp index 9dfc33c00f98342dc00c82daac9d292593f21952..83d0ef2108556224a95fcaba295c1e3f777f1456 100644 --- a/libobs-winrt/winrt-capture.cpp +++ b/libobs-winrt/winrt-capture.cpp @@ -110,6 +110,7 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height, struct winrt_capture { HWND window; bool client_area; + HMONITOR monitor; bool capture_cursor; BOOL cursor_visible; @@ -260,6 +261,53 @@ try { } #endif +static winrt::Windows::Graphics::Capture::GraphicsCaptureItem +winrt_capture_create_item(IGraphicsCaptureItemInterop *const interop_factory, + HWND window, HMONITOR monitor) +{ + winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr}; + if (window) { + try { + const HRESULT hr = interop_factory->CreateForWindow( + window, + winrt::guid_of(), + reinterpret_cast( + winrt::put_abi(item))); + if (FAILED(hr)) + blog(LOG_ERROR, "CreateForWindow (0x%08X)", hr); + } catch (winrt::hresult_error &err) { + blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", + err.to_abi(), err.message().c_str()); + } catch (...) { + blog(LOG_ERROR, "CreateForWindow (0x%08X)", + winrt::to_hresult()); + } + } else { + assert(monitor); + + try { + const HRESULT hr = interop_factory->CreateForMonitor( + monitor, + winrt::guid_of(), + reinterpret_cast( + winrt::put_abi(item))); + if (FAILED(hr)) + blog(LOG_ERROR, "CreateForMonitor (0x%08X)", + hr); + } catch (winrt::hresult_error &err) { + blog(LOG_ERROR, "CreateForMonitor (0x%08X): %ls", + err.to_abi(), err.message().c_str()); + } catch (...) { + blog(LOG_ERROR, "CreateForMonitor (0x%08X)", + winrt::to_hresult()); + } + } + + return item; +} + static void winrt_capture_device_loss_rebuild(void *device_void, void *data) { winrt_capture *capture = static_cast(data); @@ -268,20 +316,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) winrt::Windows::Graphics::Capture::GraphicsCaptureItem>(); auto interop_factory = activation_factory.as(); - winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr}; - try { - interop_factory->CreateForWindow( - capture->window, - winrt::guid_of(), - reinterpret_cast(winrt::put_abi(item))); - } catch (winrt::hresult_error &err) { - blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", err.to_abi(), - err.message().c_str()); - } catch (...) { - blog(LOG_ERROR, "CreateForWindow (0x%08X)", - winrt::to_hresult()); - } + winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = + winrt_capture_create_item(interop_factory.get(), + capture->window, capture->monitor); ID3D11Device *const d3d_device = (ID3D11Device *)device_void; ComPtr dxgi_device; @@ -341,8 +378,10 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) } } -extern "C" EXPORT struct winrt_capture * -winrt_capture_init(BOOL cursor, HWND window, BOOL client_area) +static struct winrt_capture *winrt_capture_init_internal(BOOL cursor, + HWND window, + BOOL client_area, + HMONITOR monitor) try { ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj(); ComPtr dxgi_device; @@ -365,26 +404,11 @@ try { winrt::Windows::Graphics::Capture::GraphicsCaptureItem>(); auto interop_factory = activation_factory.as(); - winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr}; - try { - hr = interop_factory->CreateForWindow( - window, - winrt::guid_of(), - reinterpret_cast(winrt::put_abi(item))); - if (FAILED(hr)) { - blog(LOG_ERROR, "CreateForWindow (0x%08X)", hr); - return nullptr; - } - } catch (winrt::hresult_error &err) { - blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", err.to_abi(), - err.message().c_str()); + winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = + winrt_capture_create_item(interop_factory.get(), window, + monitor); + if (!item) return nullptr; - } catch (...) { - blog(LOG_ERROR, "CreateForWindow (0x%08X)", - winrt::to_hresult()); - return nullptr; - } const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device = inspectable.aswindow = window; capture->client_area = client_area; + capture->monitor = monitor; capture->capture_cursor = cursor && cursor_toggle_supported; capture->cursor_visible = cursor; capture->item = item; @@ -456,6 +481,18 @@ try { return nullptr; } +extern "C" EXPORT struct winrt_capture * +winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area) +{ + return winrt_capture_init_internal(cursor, window, client_area, NULL); +} + +extern "C" EXPORT struct winrt_capture * +winrt_capture_init_monitor(BOOL cursor, HMONITOR monitor) +{ + return winrt_capture_init_internal(cursor, NULL, false, monitor); +} + extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture) { if (capture) { diff --git a/libobs-winrt/winrt-capture.h b/libobs-winrt/winrt-capture.h index 96daa1c8d5a6bacbd246f61cfa1b9dded8099876..8b3bafe6a965232d692e8cf431924a594182b50c 100644 --- a/libobs-winrt/winrt-capture.h +++ b/libobs-winrt/winrt-capture.h @@ -11,8 +11,10 @@ extern "C" { EXPORT BOOL winrt_capture_supported(); EXPORT BOOL winrt_capture_cursor_toggle_supported(); -EXPORT struct winrt_capture *winrt_capture_init(BOOL cursor, HWND window, - BOOL client_area); +EXPORT struct winrt_capture *winrt_capture_init_window(BOOL cursor, HWND window, + BOOL client_area); +EXPORT struct winrt_capture *winrt_capture_init_monitor(BOOL cursor, + HMONITOR monitor); EXPORT void winrt_capture_free(struct winrt_capture *capture); EXPORT BOOL winrt_capture_active(const struct winrt_capture *capture); diff --git a/plugins/win-capture/window-capture.c b/plugins/win-capture/window-capture.c index d307ee6be2adb320bf8898ef60e71356384e27ac..5a721697f9b6b415352b217b70731e4befe6c9fd 100644 --- a/plugins/win-capture/window-capture.c +++ b/plugins/win-capture/window-capture.c @@ -28,9 +28,8 @@ typedef BOOL (*PFN_winrt_capture_supported)(); typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)(); -typedef struct winrt_capture *(*PFN_winrt_capture_init)(BOOL cursor, - HWND window, - BOOL client_area); +typedef struct winrt_capture *(*PFN_winrt_capture_init_window)( + BOOL cursor, HWND window, BOOL client_area); typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture); typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture); @@ -46,7 +45,7 @@ struct winrt_exports { PFN_winrt_capture_supported winrt_capture_supported; PFN_winrt_capture_cursor_toggle_supported winrt_capture_cursor_toggle_supported; - PFN_winrt_capture_init winrt_capture_init; + PFN_winrt_capture_init_window winrt_capture_init_window; PFN_winrt_capture_free winrt_capture_free; PFN_winrt_capture_active winrt_capture_active; PFN_winrt_capture_show_cursor winrt_capture_show_cursor; @@ -224,7 +223,7 @@ static bool load_winrt_imports(struct winrt_exports *exports, void *module, WINRT_IMPORT(winrt_capture_supported); WINRT_IMPORT(winrt_capture_cursor_toggle_supported); - WINRT_IMPORT(winrt_capture_init); + WINRT_IMPORT(winrt_capture_init_window); WINRT_IMPORT(winrt_capture_free); WINRT_IMPORT(winrt_capture_active); WINRT_IMPORT(winrt_capture_show_cursor); @@ -544,7 +543,7 @@ static void wc_tick(void *data, float seconds) if (wc->window && (wc->capture_winrt == NULL)) { if (!wc->previously_failed) { wc->capture_winrt = - wc->exports.winrt_capture_init( + wc->exports.winrt_capture_init_window( wc->cursor, wc->window, wc->client_area);