From 12a74caf629a4f5b8dd0c8d4de13aa1aeb7ecd17 Mon Sep 17 00:00:00 2001 From: ubuntu Date: Wed, 21 Sep 2022 05:12:33 -0700 Subject: [PATCH] Add obs-websocket-api.h to deps/ Using a submodule which is not available as a package on Debian makes it difficult to package the plugin for Debian. Instead add the obs-websocket header file directly to the repo. --- deps/obs-websocket/lib/obs-websocket-api.h | 216 +++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 deps/obs-websocket/lib/obs-websocket-api.h diff --git a/deps/obs-websocket/lib/obs-websocket-api.h b/deps/obs-websocket/lib/obs-websocket-api.h new file mode 100644 index 00000000..3ab1a623 --- /dev/null +++ b/deps/obs-websocket/lib/obs-websocket-api.h @@ -0,0 +1,216 @@ +/* +obs-websocket +Copyright (C) 2016-2021 Stephane Lepin +Copyright (C) 2020-2022 Kyle Manning + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see +*/ + +#ifndef _OBS_WEBSOCKET_API_H +#define _OBS_WEBSOCKET_API_H + +#include + +#define OBS_WEBSOCKET_API_VERSION 2 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *obs_websocket_vendor; +typedef void (*obs_websocket_request_callback_function)(obs_data_t *, obs_data_t *, void *); + +struct obs_websocket_request_response { + unsigned int status_code; + char *comment; + char *response_data; // JSON string, because obs_data_t* only supports array, so conversions would break API. +}; + +/* ==================== INTERNAL DEFINITIONS ==================== */ + +struct obs_websocket_request_callback { + obs_websocket_request_callback_function callback; + void *priv_data; +}; + +inline proc_handler_t *_ph; + +/* ==================== INTERNAL API FUNCTIONS ==================== */ + +static inline proc_handler_t *obs_websocket_get_ph(void) +{ + proc_handler_t *global_ph = obs_get_proc_handler(); + assert(global_ph != NULL); + + calldata_t cd = {0}; + if (!proc_handler_call(global_ph, "obs_websocket_api_get_ph", &cd)) + blog(LOG_DEBUG, "Unable to fetch obs-websocket proc handler object. obs-websocket not installed?"); + proc_handler_t *ret = (proc_handler_t *)calldata_ptr(&cd, "ph"); + calldata_free(&cd); + + return ret; +} + +static inline bool obs_websocket_ensure_ph(void) +{ + if (!_ph) + _ph = obs_websocket_get_ph(); + return _ph != NULL; +} + +static inline bool obs_websocket_vendor_run_simple_proc(obs_websocket_vendor vendor, const char *proc_name, calldata_t *cd) +{ + if (!obs_websocket_ensure_ph()) + return false; + + if (!vendor || !proc_name || !strlen(proc_name) || !cd) + return false; + + calldata_set_ptr(cd, "vendor", vendor); + + proc_handler_call(_ph, proc_name, cd); + return calldata_bool(cd, "success"); +} + +/* ==================== GENERAL API FUNCTIONS ==================== */ + +// Gets the API version built with the obs-websocket plugin +static inline unsigned int obs_websocket_get_api_version(void) +{ + if (!obs_websocket_ensure_ph()) + return 0; + + calldata_t cd = {0}; + + if (!proc_handler_call(_ph, "get_api_version", &cd)) + return 1; // API v1 does not include get_api_version + + unsigned int ret = calldata_int(&cd, "version"); + + calldata_free(&cd); + + return ret; +} + +// Calls an obs-websocket request. Free response with `obs_websocket_request_response_free()` +static inline obs_websocket_request_response *obs_websocket_call_request(const char *request_type, obs_data_t *request_data = NULL) +{ + if (!obs_websocket_ensure_ph()) + return NULL; + + const char *request_data_string = NULL; + if (request_data) + request_data_string = obs_data_get_json(request_data); + + calldata_t cd = {0}; + + calldata_set_string(&cd, "request_type", request_type); + calldata_set_string(&cd, "request_data", request_data_string); + + proc_handler_call(_ph, "call_request", &cd); + + auto ret = (struct obs_websocket_request_response *)calldata_ptr(&cd, "response"); + + calldata_free(&cd); + + return ret; +} + +// Free a request response object returned by `obs_websocket_call_request()` +static inline void obs_websocket_request_response_free(struct obs_websocket_request_response *response) +{ + if (!response) + return; + + if (response->comment) + bfree(response->comment); + if (response->response_data) + bfree(response->response_data); + bfree(response); +} + +/* ==================== VENDOR API FUNCTIONS ==================== */ + +// ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK! +// Registers a new "vendor" (Example: obs-ndi) +static inline obs_websocket_vendor obs_websocket_register_vendor(const char *vendor_name) +{ + if (!obs_websocket_ensure_ph()) + return NULL; + + calldata_t cd = {0}; + + calldata_set_string(&cd, "name", vendor_name); + + proc_handler_call(_ph, "vendor_register", &cd); + obs_websocket_vendor ret = calldata_ptr(&cd, "vendor"); + calldata_free(&cd); + + return ret; +} + +// Registers a new request for a vendor +static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor vendor, const char *request_type, + obs_websocket_request_callback_function request_callback, void *priv_data) +{ + calldata_t cd = {0}; + + struct obs_websocket_request_callback cb = {}; + cb.callback = request_callback; + cb.priv_data = priv_data; + + calldata_set_string(&cd, "type", request_type); + calldata_set_ptr(&cd, "callback", &cb); + + bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_register", &cd); + calldata_free(&cd); + + return success; +} + +// Unregisters an existing vendor request +static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor vendor, const char *request_type) +{ + calldata_t cd = {0}; + + calldata_set_string(&cd, "type", request_type); + + bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_request_unregister", &cd); + calldata_free(&cd); + + return success; +} + +// Does not affect event_data refcount. +// Emits an event under the vendor's name +static inline bool obs_websocket_vendor_emit_event(obs_websocket_vendor vendor, const char *event_name, obs_data_t *event_data) +{ + calldata_t cd = {0}; + + calldata_set_string(&cd, "type", event_name); + calldata_set_ptr(&cd, "data", (void *)event_data); + + bool success = obs_websocket_vendor_run_simple_proc(vendor, "vendor_event_emit", &cd); + calldata_free(&cd); + + return success; +} + +/* ==================== END API FUNCTIONS ==================== */ + +#ifdef __cplusplus +} +#endif + +#endif