From b8fcf0355ce614aa4fadef4ccece894a24339a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 12:44:13 +0100 Subject: [PATCH 1/7] requests(GetSourceFilters): add "enabled" status field --- src/Utils.cpp | 21 ++++++++++++++------- src/Utils.h | 1 + src/WSRequestHandler_Sources.cpp | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index ae8a2aa0..be5995e2 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -735,6 +735,18 @@ obs_data_t* Utils::GetSceneItemPropertiesData(obs_sceneitem_t* sceneItem) { return data; } +obs_data_t* Utils::GetSourceFilterInfo(obs_source_t* filter, bool includeSettings) +{ + obs_data_t* data = obs_data_create(); + obs_data_set_bool(data, "enabled", obs_source_enabled(filter)); + obs_data_set_string(data, "type", obs_source_get_id(filter)); + obs_data_set_string(data, "name", obs_source_get_name(filter)); + if (includeSettings) { + obs_data_set_obj(data, "settings", obs_source_get_settings(filter)); + } + return data; +} + obs_data_array_t* Utils::GetSourceFiltersList(obs_source_t* source, bool includeSettings) { struct enum_params { @@ -755,13 +767,8 @@ obs_data_array_t* Utils::GetSourceFiltersList(obs_source_t* source, bool include { auto enumParams = reinterpret_cast(param); - OBSDataAutoRelease filter = obs_data_create(); - obs_data_set_string(filter, "type", obs_source_get_id(child)); - obs_data_set_string(filter, "name", obs_source_get_name(child)); - if (enumParams->includeSettings) { - obs_data_set_obj(filter, "settings", obs_source_get_settings(child)); - } - obs_data_array_push_back(enumParams->filters, filter); + OBSDataAutoRelease filterData = Utils::GetSourceFilterInfo(child, enumParams->includeSettings); + obs_data_array_push_back(enumParams->filters, filterData); }, &enumParams); return enumParams.filters; diff --git a/src/Utils.h b/src/Utils.h index 6de57eec..89f01acc 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -48,6 +48,7 @@ class Utils { static obs_scene_t* GetSceneFromNameOrCurrent(QString sceneName); static obs_data_t* GetSceneItemPropertiesData(obs_sceneitem_t* item); + static obs_data_t* GetSourceFilterInfo(obs_source_t* filter, bool includeSettings); static obs_data_array_t* GetSourceFiltersList(obs_source_t* source, bool includeSettings); static bool IsValidAlignment(const uint32_t alignment); diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index 87ff010a..9e5716d0 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1061,6 +1061,7 @@ HandlerResponse WSRequestHandler::HandleGetSpecialSources(WSRequestHandler* req) * @param {String} `sourceName` Source name * * @return {Array} `filters` List of filters for the specified source +* @return {Boolean} `filters.*.enabled` Filter status (enabled or not) * @return {String} `filters.*.type` Filter type * @return {String} `filters.*.name` Filter name * @return {Object} `filters.*.settings` Filter settings From 897f1153630af58c5562efffcee88644134043a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 12:47:10 +0100 Subject: [PATCH 2/7] requests(sources): add GetSourceFilterInfo method --- src/WSRequestHandler.cpp | 1 + src/WSRequestHandler.h | 1 + src/WSRequestHandler_Sources.cpp | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/WSRequestHandler.cpp b/src/WSRequestHandler.cpp index 2ff897fe..cc73a5bd 100644 --- a/src/WSRequestHandler.cpp +++ b/src/WSRequestHandler.cpp @@ -95,6 +95,7 @@ QHash WSRequestHandler::messageM { "TakeSourceScreenshot", WSRequestHandler::HandleTakeSourceScreenshot }, { "GetSourceFilters", WSRequestHandler::HandleGetSourceFilters }, + { "GetSourceFilterInfo", WSRequestHandler::HandleGetSourceFilterInfo }, { "AddFilterToSource", WSRequestHandler::HandleAddFilterToSource }, { "RemoveFilterFromSource", WSRequestHandler::HandleRemoveFilterFromSource }, { "ReorderSourceFilter", WSRequestHandler::HandleReorderSourceFilter }, diff --git a/src/WSRequestHandler.h b/src/WSRequestHandler.h index bee9566b..913fee6d 100644 --- a/src/WSRequestHandler.h +++ b/src/WSRequestHandler.h @@ -139,6 +139,7 @@ class WSRequestHandler : public QObject { static HandlerResponse HandleTakeSourceScreenshot(WSRequestHandler* req); static HandlerResponse HandleGetSourceFilters(WSRequestHandler* req); + static HandlerResponse HandleGetSourceFilterInfo(WSRequestHandler* req); static HandlerResponse HandleAddFilterToSource(WSRequestHandler* req); static HandlerResponse HandleRemoveFilterFromSource(WSRequestHandler* req); static HandlerResponse HandleReorderSourceFilter(WSRequestHandler* req); diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index 9e5716d0..44eb7337 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1090,6 +1090,44 @@ HandlerResponse WSRequestHandler::HandleGetSourceFilters(WSRequestHandler* req) return req->SendOKResponse(response); } +/** +* List filters applied to a source +* +* @param {String} `sourceName` Source name +* @param {String} `filterName` Source filter name +* +* @return {Boolean} `enabled` Filter status (enabled or not) +* @return {String} `type` Filter type +* @return {String} `name` Filter name +* @return {Object} `settings` Filter settings +* +* @api requests +* @name GetSourceFilterInfo +* @category sources +* @since 4.7.0 +*/ +HandlerResponse WSRequestHandler::HandleGetSourceFilterInfo(WSRequestHandler* req) +{ + if (!req->hasField("sourceName") || !req->hasField("filterName")) { + return req->SendErrorResponse("missing request parameters"); + } + + const char* sourceName = obs_data_get_string(req->data, "sourceName"); + OBSSourceAutoRelease source = obs_get_source_by_name(sourceName); + if (!source) { + return req->SendErrorResponse("specified source doesn't exist"); + } + + const char* filterName = obs_data_get_string(req->data, "filterName"); + OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, "filterName"); + if (!filter) { + return req->SendErrorResponse("specified filter doesn't exist on specified source"); + } + + OBSDataAutoRelease response = Utils::GetSourceFilterInfo(filter, true); + return req->SendOKResponse(response); +} + /** * Add a new filter to a source. Available source types along with their settings properties are available from `GetSourceTypesList`. * From 61af0ec9c6fb3cdf6dbf351352dc8d565265d03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 12:58:36 +0100 Subject: [PATCH 3/7] requests(sources): add SetSourceFilterVisibility method --- src/WSRequestHandler.cpp | 1 + src/WSRequestHandler.h | 1 + src/WSRequestHandler_Sources.cpp | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/WSRequestHandler.cpp b/src/WSRequestHandler.cpp index cc73a5bd..8b31c0b7 100644 --- a/src/WSRequestHandler.cpp +++ b/src/WSRequestHandler.cpp @@ -101,6 +101,7 @@ QHash WSRequestHandler::messageM { "ReorderSourceFilter", WSRequestHandler::HandleReorderSourceFilter }, { "MoveSourceFilter", WSRequestHandler::HandleMoveSourceFilter }, { "SetSourceFilterSettings", WSRequestHandler::HandleSetSourceFilterSettings }, + { "SetSourceFilterVisibility", WSRequestHandler::HandleSetSourceFilterVisibility }, { "SetCurrentSceneCollection", WSRequestHandler::HandleSetCurrentSceneCollection }, { "GetCurrentSceneCollection", WSRequestHandler::HandleGetCurrentSceneCollection }, diff --git a/src/WSRequestHandler.h b/src/WSRequestHandler.h index 913fee6d..0e729e55 100644 --- a/src/WSRequestHandler.h +++ b/src/WSRequestHandler.h @@ -145,6 +145,7 @@ class WSRequestHandler : public QObject { static HandlerResponse HandleReorderSourceFilter(WSRequestHandler* req); static HandlerResponse HandleMoveSourceFilter(WSRequestHandler* req); static HandlerResponse HandleSetSourceFilterSettings(WSRequestHandler* req); + static HandlerResponse HandleSetSourceFilterVisibility(WSRequestHandler* req); static HandlerResponse HandleSetCurrentSceneCollection(WSRequestHandler* req); static HandlerResponse HandleGetCurrentSceneCollection(WSRequestHandler* req); diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index 44eb7337..b84e38db 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1378,6 +1378,42 @@ HandlerResponse WSRequestHandler::HandleSetSourceFilterSettings(WSRequestHandler return req->SendOKResponse(); } +/** +* Change the visibility/enabled state of a filter +* +* @param {String} `sourceName` Source name +* @param {String} `filterName` Source filter name +* @param {String} `filterEnabled` New filter state +* +* @api requests +* @name EnableSourceFilter +* @category sources +* @since 4.7.0 +*/ +HandlerResponse WSRequestHandler::HandleSetSourceFilterVisibility(WSRequestHandler* req) +{ + if (!req->hasField("sourceName") || !req->hasField("filterName") || !req->hasField("filterEnabled")) { + return req->SendErrorResponse("missing request parameters"); + } + + const char* sourceName = obs_data_get_string(req->data, "sourceName"); + OBSSourceAutoRelease source = obs_get_source_by_name(sourceName); + if (!source) { + return req->SendErrorResponse("specified source doesn't exist"); + } + + const char* filterName = obs_data_get_string(req->data, "filterName"); + OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, "filterName"); + if (!filter) { + return req->SendErrorResponse("specified filter doesn't exist on specified source"); + } + + bool filterEnabled = obs_data_get_string(req->data, "filterEnabled"); + obs_source_set_enabled(filter, filterEnabled); + + return req->SendOKResponse(); +} + /** * Takes a picture snapshot of a source and then can either or both: * - Send it over as a Data URI (base64-encoded data) in the response (by specifying `embedPictureFormat` in the request) From be897c4df25eccb718468724b8792cf859e5773f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 13:42:16 +0100 Subject: [PATCH 4/7] requests(sources): fix typo --- src/WSRequestHandler_Sources.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index b84e38db..d4ad23fa 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1119,7 +1119,7 @@ HandlerResponse WSRequestHandler::HandleGetSourceFilterInfo(WSRequestHandler* re } const char* filterName = obs_data_get_string(req->data, "filterName"); - OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, "filterName"); + OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName); if (!filter) { return req->SendErrorResponse("specified filter doesn't exist on specified source"); } @@ -1403,7 +1403,7 @@ HandlerResponse WSRequestHandler::HandleSetSourceFilterVisibility(WSRequestHandl } const char* filterName = obs_data_get_string(req->data, "filterName"); - OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, "filterName"); + OBSSourceAutoRelease filter = obs_source_get_filter_by_name(source, filterName); if (!filter) { return req->SendErrorResponse("specified filter doesn't exist on specified source"); } From c51f20eb99ecfe2b51f7eee5d0d7d5afea60b263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 13:43:33 +0100 Subject: [PATCH 5/7] requests(SetSourceFilterVisibility): fix parameter value --- src/WSRequestHandler_Sources.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index d4ad23fa..775f0705 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1408,7 +1408,7 @@ HandlerResponse WSRequestHandler::HandleSetSourceFilterVisibility(WSRequestHandl return req->SendErrorResponse("specified filter doesn't exist on specified source"); } - bool filterEnabled = obs_data_get_string(req->data, "filterEnabled"); + bool filterEnabled = obs_data_get_bool(req->data, "filterEnabled"); obs_source_set_enabled(filter, filterEnabled); return req->SendOKResponse(); From a3e0abb6cee94536d327b31742ce435aed715b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 14:12:37 +0100 Subject: [PATCH 6/7] events: add SourceFilterVisibilityChanged --- src/WSEvents.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/WSEvents.h | 4 ++++ 2 files changed, 61 insertions(+) diff --git a/src/WSEvents.cpp b/src/WSEvents.cpp index a1979492..4e978cc4 100644 --- a/src/WSEvents.cpp +++ b/src/WSEvents.cpp @@ -340,6 +340,26 @@ void WSEvents::disconnectSourceSignals(obs_source_t* source) { signal_handler_disconnect(sh, "transition_start", OnTransitionBegin, this); } +void WSEvents::connectFilterSignals(obs_source_t* filter) { + if (!filter) { + return; + } + + signal_handler_t* sh = obs_source_get_signal_handler(filter); + + signal_handler_connect(sh, "enable", OnSourceFilterVisibilityChanged, this); +} + +void WSEvents::disconnectFilterSignals(obs_source_t* filter) { + if (!filter) { + return; + } + + signal_handler_t* sh = obs_source_get_signal_handler(filter); + + signal_handler_disconnect(sh, "enable", OnSourceFilterVisibilityChanged, this); +} + void WSEvents::hookTransitionBeginEvent() { obs_frontend_source_list transitions = {}; obs_frontend_get_transitions(&transitions); @@ -1180,6 +1200,8 @@ void WSEvents::OnSourceFilterAdded(void* param, calldata_t* data) { if (!filter) { return; } + + self->connectFilterSignals(filter); OBSDataAutoRelease filterSettings = obs_source_get_settings(filter); @@ -1212,6 +1234,11 @@ void WSEvents::OnSourceFilterRemoved(void* param, calldata_t* data) { } obs_source_t* filter = calldata_get_pointer(data, "filter"); + if (!filter) { + return; + } + + self->disconnectFilterSignals(filter); OBSDataAutoRelease fields = obs_data_create(); obs_data_set_string(fields, "sourceName", obs_source_get_name(source)); @@ -1220,6 +1247,36 @@ void WSEvents::OnSourceFilterRemoved(void* param, calldata_t* data) { self->broadcastUpdate("SourceFilterRemoved", fields); } +/** + * The visibility/enabled state of a filter changed + * + * @return {String} `sourceName` Source name + * @return {String} `filterName` Filter name + * @return {Boolean} `filterEnabled` New filter state + * + * @api events + * @name SourceFilterVisibilityChanged + * @category sources + * @since 4.7.0 + */ +void WSEvents::OnSourceFilterVisibilityChanged(void* param, calldata_t* data) { + auto self = reinterpret_cast(param); + + OBSSource source = calldata_get_pointer(data, "source"); + if (!source) { + return; + } + + OBSSource parent = obs_filter_get_parent(source); + + OBSDataAutoRelease fields = obs_data_create(); + obs_data_set_string(fields, "sourceName", obs_source_get_name(parent)); + obs_data_set_string(fields, "filterName", obs_source_get_name(source)); + obs_data_set_bool(fields, "filterEnabled", obs_source_enabled(source)); + + self->broadcastUpdate("SourceFilterVisibilityChanged", fields); +} + /** * Filters in a source have been reordered. * diff --git a/src/WSEvents.h b/src/WSEvents.h index 85be443f..684fe654 100644 --- a/src/WSEvents.h +++ b/src/WSEvents.h @@ -40,6 +40,9 @@ public: void connectSourceSignals(obs_source_t* source); void disconnectSourceSignals(obs_source_t* source); + void connectFilterSignals(obs_source_t* filter); + void disconnectFilterSignals(obs_source_t* filter); + void hookTransitionBeginEvent(); void unhookTransitionBeginEvent(); @@ -126,6 +129,7 @@ private: static void OnSourceFilterAdded(void* param, calldata_t* data); static void OnSourceFilterRemoved(void* param, calldata_t* data); + static void OnSourceFilterVisibilityChanged(void* param, calldata_t* data); static void OnSourceFilterOrderChanged(void* param, calldata_t* data); static void OnSceneReordered(void* param, calldata_t* data); From a8e5171b40d173e5fa6e88fa524665b5b90f6c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lepin?= Date: Mon, 11 Nov 2019 14:27:40 +0100 Subject: [PATCH 7/7] utils(GetSourceFilterInfo): fix settings memory leak --- src/Utils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index be5995e2..243faf35 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -742,7 +742,8 @@ obs_data_t* Utils::GetSourceFilterInfo(obs_source_t* filter, bool includeSetting obs_data_set_string(data, "type", obs_source_get_id(filter)); obs_data_set_string(data, "name", obs_source_get_name(filter)); if (includeSettings) { - obs_data_set_obj(data, "settings", obs_source_get_settings(filter)); + OBSDataAutoRelease settings = obs_source_get_settings(filter); + obs_data_set_obj(data, "settings", settings); } return data; }