Просмотр исходного кода

win-capture: Add hook signal and proc for window capture

Penwywern 2 лет назад
Родитель
Сommit
82beae249a
1 измененных файлов с 135 добавлено и 0 удалено
  1. 135 0
      plugins/win-capture/window-capture.c

+ 135 - 0
plugins/win-capture/window-capture.c

@@ -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);
 				}
 			}
 		}