mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-08-31 02:13:51 +08:00
win-capture: Add hook signal and proc for window capture
This commit is contained in:
@@ -92,6 +92,7 @@ struct window_capture {
|
||||
bool compatibility;
|
||||
bool client_area;
|
||||
bool force_sdr;
|
||||
bool hooked;
|
||||
|
||||
struct dc_capture capture;
|
||||
|
||||
@@ -225,6 +226,34 @@ static void update_settings(struct window_capture *wc, obs_data_t *s)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void wc_get_hooked(void *data, calldata_t *cd)
|
||||
{
|
||||
struct window_capture *wc = data;
|
||||
if (!wc)
|
||||
return;
|
||||
|
||||
if (wc->hooked && wc->window) {
|
||||
calldata_set_bool(cd, "hooked", true);
|
||||
struct dstr title = {0};
|
||||
struct dstr class = {0};
|
||||
struct dstr executable = {0};
|
||||
ms_get_window_title(&title, wc->window);
|
||||
ms_get_window_class(&class, wc->window);
|
||||
ms_get_window_exe(&executable, wc->window);
|
||||
calldata_set_string(cd, "title", title.array);
|
||||
calldata_set_string(cd, "class", class.array);
|
||||
calldata_set_string(cd, "executable", executable.array);
|
||||
dstr_free(&title);
|
||||
dstr_free(&class);
|
||||
dstr_free(&executable);
|
||||
} else {
|
||||
calldata_set_bool(cd, "hooked", false);
|
||||
calldata_set_string(cd, "title", "");
|
||||
calldata_set_string(cd, "class", "");
|
||||
calldata_set_string(cd, "executable", "");
|
||||
}
|
||||
}
|
||||
|
||||
static const char *wc_getname(void *unused)
|
||||
{
|
||||
UNUSED_PARAMETER(unused);
|
||||
@@ -308,6 +337,19 @@ static void *wc_create(obs_data_t *settings, obs_source_t *source)
|
||||
get_window_dpi_awareness_context;
|
||||
}
|
||||
}
|
||||
wc->hooked = false;
|
||||
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(source);
|
||||
signal_handler_add(sh, "void unhooked(ptr source)");
|
||||
signal_handler_add(
|
||||
sh,
|
||||
"void hooked(ptr source, string title, string class, string executable)");
|
||||
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_add(
|
||||
ph,
|
||||
"void get_hooked(out bool hooked, out string title, out string class, out string executable)",
|
||||
wc_get_hooked, wc);
|
||||
|
||||
update_settings(wc, settings);
|
||||
log_settings(wc, settings);
|
||||
@@ -537,6 +579,17 @@ static void wc_hide(void *data)
|
||||
}
|
||||
|
||||
memset(&wc->last_rect, 0, sizeof(wc->last_rect));
|
||||
|
||||
if (wc->hooked) {
|
||||
wc->hooked = false;
|
||||
|
||||
signal_handler_t *sh =
|
||||
obs_source_get_signal_handler(wc->source);
|
||||
calldata_t data = {0};
|
||||
calldata_set_ptr(&data, "source", wc->source);
|
||||
signal_handler_signal(sh, "unhooked", &data);
|
||||
calldata_free(&data);
|
||||
}
|
||||
}
|
||||
|
||||
static void wc_tick(void *data, float seconds)
|
||||
@@ -549,6 +602,17 @@ static void wc_tick(void *data, float seconds)
|
||||
return;
|
||||
|
||||
if (!wc->window || !IsWindow(wc->window)) {
|
||||
if (wc->hooked) {
|
||||
wc->hooked = false;
|
||||
|
||||
signal_handler_t *sh =
|
||||
obs_source_get_signal_handler(wc->source);
|
||||
calldata_t data = {0};
|
||||
calldata_set_ptr(&data, "source", wc->source);
|
||||
signal_handler_signal(sh, "unhooked", &data);
|
||||
calldata_free(&data);
|
||||
}
|
||||
|
||||
if (!wc->title && !wc->class) {
|
||||
if (wc->capture.valid)
|
||||
dc_capture_free(&wc->capture);
|
||||
@@ -611,6 +675,17 @@ static void wc_tick(void *data, float seconds)
|
||||
!wc->exports.winrt_capture_show_cursor(wc->capture_winrt,
|
||||
!cursor_hidden)) {
|
||||
force_reset(wc);
|
||||
if (wc->hooked) {
|
||||
wc->hooked = false;
|
||||
|
||||
signal_handler_t *sh =
|
||||
obs_source_get_signal_handler(
|
||||
wc->source);
|
||||
calldata_t data = {0};
|
||||
calldata_set_ptr(&data, "source", wc->source);
|
||||
signal_handler_signal(sh, "unhooked", &data);
|
||||
calldata_free(&data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -655,6 +730,35 @@ static void wc_tick(void *data, float seconds)
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top, wc->cursor,
|
||||
wc->compatibility);
|
||||
if (!wc->hooked && wc->capture.valid) {
|
||||
wc->hooked = true;
|
||||
|
||||
signal_handler_t *sh =
|
||||
obs_source_get_signal_handler(
|
||||
wc->source);
|
||||
calldata_t data = {0};
|
||||
struct dstr title = {0};
|
||||
struct dstr class = {0};
|
||||
struct dstr executable = {0};
|
||||
|
||||
ms_get_window_title(&title, wc->window);
|
||||
ms_get_window_class(&class, wc->window);
|
||||
ms_get_window_exe(&executable, wc->window);
|
||||
|
||||
calldata_set_ptr(&data, "source", wc->source);
|
||||
calldata_set_string(&data, "title",
|
||||
title.array);
|
||||
calldata_set_string(&data, "class",
|
||||
class.array);
|
||||
calldata_set_string(&data, "executable",
|
||||
executable.array);
|
||||
signal_handler_signal(sh, "hooked", &data);
|
||||
|
||||
dstr_free(&title);
|
||||
dstr_free(&class);
|
||||
dstr_free(&executable);
|
||||
calldata_free(&data);
|
||||
}
|
||||
}
|
||||
|
||||
dc_capture_capture(&wc->capture, wc->window);
|
||||
@@ -671,6 +775,37 @@ static void wc_tick(void *data, float seconds)
|
||||
|
||||
if (!wc->capture_winrt) {
|
||||
wc->previously_failed = true;
|
||||
} else if (!wc->hooked) {
|
||||
wc->hooked = true;
|
||||
|
||||
signal_handler_t *sh =
|
||||
obs_source_get_signal_handler(
|
||||
wc->source);
|
||||
calldata_t data = {0};
|
||||
struct dstr title = {0};
|
||||
struct dstr class = {0};
|
||||
struct dstr executable = {0};
|
||||
|
||||
ms_get_window_title(&title, wc->window);
|
||||
ms_get_window_class(&class, wc->window);
|
||||
ms_get_window_exe(&executable,
|
||||
wc->window);
|
||||
|
||||
calldata_set_ptr(&data, "source",
|
||||
wc->source);
|
||||
calldata_set_string(&data, "title",
|
||||
title.array);
|
||||
calldata_set_string(&data, "class",
|
||||
class.array);
|
||||
calldata_set_string(&data, "executable",
|
||||
executable.array);
|
||||
signal_handler_signal(sh, "hooked",
|
||||
&data);
|
||||
|
||||
dstr_free(&title);
|
||||
dstr_free(&class);
|
||||
dstr_free(&executable);
|
||||
calldata_free(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user