UI: Add front-end API library
Allows manipulating and modifying the front-end via plugins.
This commit is contained in:
20
UI/obs-frontend-api/CMakeLists.txt
Normal file
20
UI/obs-frontend-api/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
project(obs-frontend-api)
|
||||
|
||||
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
|
||||
|
||||
add_definitions(-DLIBOBS_EXPORTS)
|
||||
|
||||
set(obs-frontend-api_SOURCES
|
||||
obs-frontend-api.cpp)
|
||||
|
||||
set(obs-frontend-api_HEADERS
|
||||
obs-frontend-internal.hpp
|
||||
obs-frontend-api.h)
|
||||
|
||||
add_library(obs-frontend-api SHARED
|
||||
${obs-frontend-api_SOURCES}
|
||||
${obs-frontend-api_HEADERS})
|
||||
target_link_libraries(obs-frontend-api
|
||||
libobs)
|
||||
|
||||
install_obs_core(obs-frontend-api)
|
295
UI/obs-frontend-api/obs-frontend-api.cpp
Normal file
295
UI/obs-frontend-api/obs-frontend-api.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
#include "obs-frontend-internal.hpp"
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static unique_ptr<obs_frontend_callbacks> c;
|
||||
|
||||
void obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks)
|
||||
{
|
||||
c.reset(callbacks);
|
||||
}
|
||||
|
||||
static inline bool callbacks_valid_(const char *func_name)
|
||||
{
|
||||
if (!c) {
|
||||
blog(LOG_WARNING, "Tried to call %s with no callbacks!",
|
||||
func_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define callbacks_valid() callbacks_valid_(__FUNCTION__)
|
||||
|
||||
static char **convert_string_list(vector<string> &strings)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t string_data_offset = (strings.size() + 1) * sizeof(char*);
|
||||
uint8_t *out;
|
||||
char **ptr_list;
|
||||
char *string_data;
|
||||
|
||||
size += string_data_offset;
|
||||
|
||||
for (auto &str : strings)
|
||||
size += str.size() + 1;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
out = (uint8_t*)bmalloc(size);
|
||||
ptr_list = (char**)out;
|
||||
string_data = (char*)(out + string_data_offset);
|
||||
|
||||
for (auto &str : strings) {
|
||||
*ptr_list = string_data;
|
||||
memcpy(string_data, str.c_str(), str.size() + 1);
|
||||
|
||||
ptr_list++;
|
||||
string_data += str.size() + 1;
|
||||
}
|
||||
|
||||
*ptr_list = nullptr;
|
||||
return (char**)out;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void *obs_frontend_get_main_window(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_main_window()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void *obs_frontend_get_main_window_handle(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_main_window_handle()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
char **obs_frontend_get_scene_names(void)
|
||||
{
|
||||
if (!callbacks_valid())
|
||||
return NULL;
|
||||
|
||||
struct obs_frontend_source_list sources = {};
|
||||
vector<string> names;
|
||||
c->obs_frontend_get_scenes(&sources);
|
||||
|
||||
for (size_t i = 0; i < sources.sources.num; i++) {
|
||||
obs_source_t *source = sources.sources.array[i];
|
||||
const char *name = obs_source_get_name(source);
|
||||
names.emplace_back(name);
|
||||
}
|
||||
|
||||
obs_frontend_source_list_free(&sources);
|
||||
return convert_string_list(names);
|
||||
}
|
||||
|
||||
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_get_scenes(sources);
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_scene(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_scene()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_scene(obs_source_t *scene)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_set_current_scene(scene);
|
||||
}
|
||||
|
||||
void obs_frontend_get_transitions(struct obs_frontend_source_list *sources)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_get_transitions(sources);
|
||||
}
|
||||
|
||||
obs_source_t *obs_frontend_get_current_transition(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_transition()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_transition(obs_source_t *transition)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_set_current_transition(transition);
|
||||
}
|
||||
|
||||
char **obs_frontend_get_scene_collections(void)
|
||||
{
|
||||
if (!callbacks_valid())
|
||||
return nullptr;
|
||||
|
||||
vector<string> strings;
|
||||
c->obs_frontend_get_scene_collections(strings);
|
||||
return convert_string_list(strings);
|
||||
}
|
||||
|
||||
char *obs_frontend_get_current_scene_collection(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_scene_collection()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_scene_collection(const char *collection)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_set_current_scene_collection(collection);
|
||||
}
|
||||
|
||||
char **obs_frontend_get_profiles(void)
|
||||
{
|
||||
if (!callbacks_valid())
|
||||
return nullptr;
|
||||
|
||||
vector<string> strings;
|
||||
c->obs_frontend_get_profiles(strings);
|
||||
return convert_string_list(strings);
|
||||
}
|
||||
|
||||
char *obs_frontend_get_current_profile(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_current_profile()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_set_current_profile(const char *profile)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_set_current_profile(profile);
|
||||
}
|
||||
|
||||
void obs_frontend_streaming_start(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_streaming_start();
|
||||
}
|
||||
|
||||
void obs_frontend_streaming_stop(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_streaming_stop();
|
||||
}
|
||||
|
||||
bool obs_frontend_streaming_active(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_streaming_active()
|
||||
: false;
|
||||
}
|
||||
|
||||
void obs_frontend_recording_start(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_recording_start();
|
||||
}
|
||||
|
||||
void obs_frontend_recording_stop(void)
|
||||
{
|
||||
if (callbacks_valid()) c->obs_frontend_recording_stop();
|
||||
}
|
||||
|
||||
bool obs_frontend_recording_active(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_recording_active()
|
||||
: false;
|
||||
}
|
||||
|
||||
void *obs_frontend_add_tools_menu_qaction(const char *name)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_add_tools_menu_qaction(name)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_add_tools_menu_item(name, callback,
|
||||
private_data);
|
||||
}
|
||||
|
||||
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_add_event_callback(callback, private_data);
|
||||
}
|
||||
|
||||
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_remove_event_callback(callback, private_data);
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_streaming_output(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_streaming_output()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
obs_output_t *obs_frontend_get_recording_output(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_recording_output()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_profile_config(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_profile_config()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
config_t *obs_frontend_get_global_config(void)
|
||||
{
|
||||
return !!callbacks_valid()
|
||||
? c->obs_frontend_get_global_config()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void obs_frontend_save(void)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_save();
|
||||
}
|
||||
|
||||
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_add_save_callback(callback, private_data);
|
||||
}
|
||||
|
||||
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_remove_save_callback(callback, private_data);
|
||||
}
|
||||
|
||||
void obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_push_ui_translation(translate);
|
||||
}
|
||||
|
||||
void obs_frontend_pop_ui_translation(void)
|
||||
{
|
||||
if (callbacks_valid())
|
||||
c->obs_frontend_pop_ui_translation();
|
||||
}
|
134
UI/obs-frontend-api/obs-frontend-api.h
Normal file
134
UI/obs-frontend-api/obs-frontend-api.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
#include <obs.h>
|
||||
#include <util/darray.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct config_data;
|
||||
typedef struct config_data config_t;
|
||||
|
||||
struct obs_data;
|
||||
typedef struct obs_data obs_data_t;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct obs_frontend_source_list {
|
||||
DARRAY(obs_source_t*) sources;
|
||||
};
|
||||
|
||||
static inline void obs_frontend_source_list_free(
|
||||
struct obs_frontend_source_list *source_list)
|
||||
{
|
||||
size_t num = source_list->sources.num;
|
||||
for (size_t i = 0; i < num; i++)
|
||||
obs_source_release(source_list->sources.array[i]);
|
||||
da_free(source_list->sources);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* NOTE: Functions that return char** string lists are a single allocation of
|
||||
* memory with pointers to itself. Free with a single call to bfree on the
|
||||
* base char** pointer. */
|
||||
|
||||
/* NOTE: User interface should not use typical Qt locale translation methods,
|
||||
* as the OBS UI bypasses it to use a custom translation implementation. Use
|
||||
* standard module translation methods, obs_module_text. For text in a Qt
|
||||
* window, use obs_frontend_push_ui_translation when the text is about to be
|
||||
* translated, and obs_frontend_pop_ui_translation when translation is
|
||||
* complete. */
|
||||
|
||||
EXPORT void *obs_frontend_get_main_window(void);
|
||||
EXPORT void *obs_frontend_get_main_window_handle(void);
|
||||
|
||||
EXPORT char **obs_frontend_get_scene_names(void);
|
||||
EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources);
|
||||
EXPORT obs_source_t *obs_frontend_get_current_scene(void);
|
||||
EXPORT void obs_frontend_set_current_scene(obs_source_t *scene);
|
||||
|
||||
EXPORT void obs_frontend_get_transitions(
|
||||
struct obs_frontend_source_list *sources);
|
||||
EXPORT obs_source_t *obs_frontend_get_current_transition(void);
|
||||
EXPORT void obs_frontend_set_current_transition(obs_source_t *transition);
|
||||
|
||||
EXPORT char **obs_frontend_get_scene_collections(void);
|
||||
EXPORT char *obs_frontend_get_current_scene_collection(void);
|
||||
EXPORT void obs_frontend_set_current_scene_collection(const char *collection);
|
||||
|
||||
EXPORT char **obs_frontend_get_profiles(void);
|
||||
EXPORT char *obs_frontend_get_current_profile(void);
|
||||
EXPORT void obs_frontend_set_current_profile(const char *profile);
|
||||
|
||||
EXPORT void obs_frontend_streaming_start(void);
|
||||
EXPORT void obs_frontend_streaming_stop(void);
|
||||
EXPORT bool obs_frontend_streaming_active(void);
|
||||
|
||||
EXPORT void obs_frontend_recording_start(void);
|
||||
EXPORT void obs_frontend_recording_stop(void);
|
||||
EXPORT bool obs_frontend_recording_active(void);
|
||||
|
||||
typedef void (*obs_frontend_cb)(void *private_data);
|
||||
|
||||
EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name);
|
||||
EXPORT void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data);
|
||||
|
||||
enum obs_frontend_event {
|
||||
OBS_FRONTEND_EVENT_STREAMING_STARTING,
|
||||
OBS_FRONTEND_EVENT_STREAMING_STARTED,
|
||||
OBS_FRONTEND_EVENT_STREAMING_STOPPING,
|
||||
OBS_FRONTEND_EVENT_STREAMING_STOPPED,
|
||||
OBS_FRONTEND_EVENT_RECORDING_STARTING,
|
||||
OBS_FRONTEND_EVENT_RECORDING_STARTED,
|
||||
OBS_FRONTEND_EVENT_RECORDING_STOPPING,
|
||||
OBS_FRONTEND_EVENT_RECORDING_STOPPED,
|
||||
OBS_FRONTEND_EVENT_SCENE_CHANGED,
|
||||
OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED,
|
||||
OBS_FRONTEND_EVENT_TRANSITION_CHANGED,
|
||||
OBS_FRONTEND_EVENT_TRANSITION_STOPPED,
|
||||
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED,
|
||||
OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED,
|
||||
OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED,
|
||||
OBS_FRONTEND_EVENT_PROFILE_CHANGED,
|
||||
OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED,
|
||||
OBS_FRONTEND_EVENT_EXIT
|
||||
};
|
||||
|
||||
typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
|
||||
void *private_data);
|
||||
|
||||
EXPORT void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data);
|
||||
EXPORT void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
|
||||
void *private_data);
|
||||
|
||||
typedef void (*obs_frontend_save_cb)(obs_data_t *save_data, bool saving,
|
||||
void *private_data);
|
||||
|
||||
EXPORT void obs_frontend_save(void);
|
||||
EXPORT void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data);
|
||||
EXPORT void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
|
||||
void *private_data);
|
||||
|
||||
EXPORT obs_output_t *obs_frontend_get_streaming_output(void);
|
||||
EXPORT obs_output_t *obs_frontend_get_recording_output(void);
|
||||
|
||||
EXPORT config_t *obs_frontend_get_profile_config(void);
|
||||
EXPORT config_t *obs_frontend_get_global_config(void);
|
||||
|
||||
typedef bool (*obs_frontend_translate_ui_cb)(const char *text,
|
||||
const char **out);
|
||||
|
||||
EXPORT void obs_frontend_push_ui_translation(
|
||||
obs_frontend_translate_ui_cb translate);
|
||||
EXPORT void obs_frontend_pop_ui_translation(void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
73
UI/obs-frontend-api/obs-frontend-internal.hpp
Normal file
73
UI/obs-frontend-api/obs-frontend-internal.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "obs-frontend-api.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct obs_frontend_callbacks {
|
||||
virtual void *obs_frontend_get_main_window(void)=0;
|
||||
virtual void *obs_frontend_get_main_window_handle(void)=0;
|
||||
|
||||
virtual void obs_frontend_get_scenes(
|
||||
struct obs_frontend_source_list *sources)=0;
|
||||
virtual obs_source_t *obs_frontend_get_current_scene(void)=0;
|
||||
virtual void obs_frontend_set_current_scene(obs_source_t *scene)=0;
|
||||
|
||||
virtual void obs_frontend_get_transitions(
|
||||
struct obs_frontend_source_list *sources)=0;
|
||||
virtual obs_source_t *obs_frontend_get_current_transition(void)=0;
|
||||
virtual void obs_frontend_set_current_transition(
|
||||
obs_source_t *transition)=0;
|
||||
|
||||
virtual void obs_frontend_get_scene_collections(
|
||||
std::vector<std::string> &strings)=0;
|
||||
virtual char *obs_frontend_get_current_scene_collection(void)=0;
|
||||
virtual void obs_frontend_set_current_scene_collection(
|
||||
const char *collection)=0;
|
||||
|
||||
virtual void obs_frontend_get_profiles(
|
||||
std::vector<std::string> &strings)=0;
|
||||
virtual char *obs_frontend_get_current_profile(void)=0;
|
||||
virtual void obs_frontend_set_current_profile(const char *profile)=0;
|
||||
|
||||
virtual void obs_frontend_streaming_start(void)=0;
|
||||
virtual void obs_frontend_streaming_stop(void)=0;
|
||||
virtual bool obs_frontend_streaming_active(void)=0;
|
||||
|
||||
virtual void obs_frontend_recording_start(void)=0;
|
||||
virtual void obs_frontend_recording_stop(void)=0;
|
||||
virtual bool obs_frontend_recording_active(void)=0;
|
||||
|
||||
virtual void *obs_frontend_add_tools_menu_qaction(const char *name)=0;
|
||||
virtual void obs_frontend_add_tools_menu_item(const char *name,
|
||||
obs_frontend_cb callback, void *private_data)=0;
|
||||
|
||||
virtual void obs_frontend_add_event_callback(
|
||||
obs_frontend_event_cb callback, void *private_data)=0;
|
||||
virtual void obs_frontend_remove_event_callback(
|
||||
obs_frontend_event_cb callback, void *private_data)=0;
|
||||
|
||||
virtual obs_output_t *obs_frontend_get_streaming_output(void)=0;
|
||||
virtual obs_output_t *obs_frontend_get_recording_output(void)=0;
|
||||
|
||||
virtual config_t *obs_frontend_get_profile_config(void)=0;
|
||||
virtual config_t *obs_frontend_get_global_config(void)=0;
|
||||
|
||||
virtual void obs_frontend_save(void)=0;
|
||||
virtual void obs_frontend_add_save_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
virtual void obs_frontend_remove_save_callback(
|
||||
obs_frontend_save_cb callback, void *private_data)=0;
|
||||
|
||||
virtual void obs_frontend_push_ui_translation(
|
||||
obs_frontend_translate_ui_cb translate)=0;
|
||||
virtual void obs_frontend_pop_ui_translation(void)=0;
|
||||
|
||||
virtual void on_load(obs_data_t *settings)=0;
|
||||
virtual void on_save(obs_data_t *settings)=0;
|
||||
virtual void on_event(enum obs_frontend_event event)=0;
|
||||
};
|
||||
|
||||
EXPORT void obs_frontend_set_callbacks_internal(
|
||||
obs_frontend_callbacks *callbacks);
|
Reference in New Issue
Block a user