diff --git a/src/Utils.cpp b/src/Utils.cpp index 5140a7ae..2752b8ab 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -24,6 +24,7 @@ with this program. If not, see #include #include #include +#include #include "obs-websocket.h" @@ -905,3 +906,52 @@ void Utils::AddSourceHelper(void *_data, obs_scene_t *scene) data->sceneItem = obs_scene_add(scene, data->source); obs_sceneitem_set_visible(data->sceneItem, data->setVisible); } + +struct obs_data_item { // Used for OBSDataGetDefaults + volatile long ref; + struct obs_data *parent; + struct obs_data_item *next; + enum obs_data_type type; + size_t name_len; + size_t data_len; + size_t data_size; + size_t default_len; + size_t default_size; + size_t autoselect_size; + size_t capacity; +}; + +obs_data_t *Utils::OBSDataGetDefaults(obs_data_t *data) +{ + obs_data_t *returnData = obs_data_create(); + obs_data_item_t *item = NULL; + + for (item = obs_data_first(data); item; obs_data_item_next(&item)) { + enum obs_data_type type = obs_data_item_gettype(item); + const char *name = (char *)item + sizeof(struct obs_data_item); + + if (type == OBS_DATA_STRING) { + const char *val = obs_data_item_get_string(item); + obs_data_set_string(returnData, name, val); + } else if (type == OBS_DATA_NUMBER) { + enum obs_data_number_type type = obs_data_item_numtype(item); + if (type == OBS_DATA_NUM_INT) { + long long val = obs_data_item_get_int(item); + obs_data_set_int(returnData, name, val); + } else { + double val = obs_data_item_get_double(item); + obs_data_set_double(returnData, name, val); + } + } else if (type == OBS_DATA_BOOLEAN) { + bool val = obs_data_item_get_bool(item); + obs_data_set_bool(returnData, name, val); + } else if (type == OBS_DATA_OBJECT) { + OBSDataAutoRelease obj = obs_data_item_get_obj(item); + obs_data_set_obj(returnData, name, obj); + } else if (type == OBS_DATA_ARRAY) { + OBSDataArrayAutoRelease array = obs_data_item_get_array(item); + obs_data_set_array(returnData, name, array); + } + } + return returnData; +} diff --git a/src/Utils.h b/src/Utils.h index 47a19f2d..d15427b5 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -94,4 +94,6 @@ namespace Utils { bool setVisible; }; void AddSourceHelper(void *_data, obs_scene_t *scene); + + obs_data_t *OBSDataGetDefaults(obs_data_t *data); }; diff --git a/src/WSRequestHandler.cpp b/src/WSRequestHandler.cpp index d3427885..0b366761 100644 --- a/src/WSRequestHandler.cpp +++ b/src/WSRequestHandler.cpp @@ -118,6 +118,7 @@ const QHash WSRequestHandler::messageMap{ { "SetSourceSettings", &WSRequestHandler::SetSourceSettings }, { "GetAudioMonitorType", &WSRequestHandler::GetAudioMonitorType }, { "SetAudioMonitorType", &WSRequestHandler::SetAudioMonitorType }, + { "GetSourceDefaultSettings", &WSRequestHandler::GetSourceDefaultSettings }, { "TakeSourceScreenshot", &WSRequestHandler::TakeSourceScreenshot }, { "GetSourceFilters", &WSRequestHandler::GetSourceFilters }, diff --git a/src/WSRequestHandler.h b/src/WSRequestHandler.h index d2da4439..16a64742 100644 --- a/src/WSRequestHandler.h +++ b/src/WSRequestHandler.h @@ -135,6 +135,7 @@ class WSRequestHandler { RpcResponse SetSourceSettings(const RpcRequest&); RpcResponse GetAudioMonitorType(const RpcRequest&); RpcResponse SetAudioMonitorType(const RpcRequest&); + RpcResponse GetSourceDefaultSettings(const RpcRequest&); RpcResponse TakeSourceScreenshot(const RpcRequest&); RpcResponse GetSourceFilters(const RpcRequest&); diff --git a/src/WSRequestHandler_Sources.cpp b/src/WSRequestHandler_Sources.cpp index 94e9a06c..8df1bf5c 100644 --- a/src/WSRequestHandler_Sources.cpp +++ b/src/WSRequestHandler_Sources.cpp @@ -1679,6 +1679,40 @@ RpcResponse WSRequestHandler::SetAudioMonitorType(const RpcRequest& request) return request.success(); } +/** +* Get the default settings for a given source type. +* +* @param {String} `sourceKind` Source name. +* +* @api requests +* @name GetSourceDefaultSettings +* @category sources +* @since 4.9.0 +*/ +RpcResponse WSRequestHandler::GetSourceDefaultSettings(const RpcRequest& request) +{ + if (!request.hasField("sourceKind")) { + return request.failed("missing request parameters"); + } + + QString sourceKind = obs_data_get_string(request.parameters(), "sourceKind"); + + if (sourceKind.isEmpty()) { + return request.failed("invalid request parameters"); + } + + OBSDataAutoRelease defaultData = obs_get_source_defaults(sourceKind.toUtf8()); + if (!defaultData) { + return request.failed("invalid sourceKind"); + } + + OBSDataAutoRelease defaultSettings = Utils::OBSDataGetDefaults(defaultData); + + OBSDataAutoRelease response = obs_data_create(); + obs_data_set_obj(response, "defaultSettings", defaultSettings); + return request.success(response); +} + /** * 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)