From 23a2228142f6736f50562f7395aa2a34a1c5858d Mon Sep 17 00:00:00 2001 From: Palana Date: Sat, 9 May 2015 03:33:55 +0200 Subject: [PATCH] libobs: Add scene item hotkeys --- libobs/obs-hotkey.c | 10 ++++++ libobs/obs-hotkey.h | 3 ++ libobs/obs-internal.h | 2 ++ libobs/obs-scene.c | 79 +++++++++++++++++++++++++++++++++++++++++++ libobs/obs-scene.h | 2 ++ libobs/obs.c | 4 +++ 6 files changed, 100 insertions(+) diff --git a/libobs/obs-hotkey.c b/libobs/obs-hotkey.c index c49316237..b5f11cb5a 100644 --- a/libobs/obs-hotkey.c +++ b/libobs/obs-hotkey.c @@ -1507,3 +1507,13 @@ void obs_hotkeys_set_audio_hotkeys_translations( SET_T(push_to_talk); #undef SET_T } + +void obs_hotkeys_set_sceneitem_hotkeys_translations( + const char *show, const char *hide) +{ +#define SET_T(n) bfree(obs->hotkeys.sceneitem_##n); \ + obs->hotkeys.sceneitem_##n = bstrdup(n) + SET_T(show); + SET_T(hide); +#undef SET_T +} diff --git a/libobs/obs-hotkey.h b/libobs/obs-hotkey.h index 17d9f850b..d5e62ce30 100644 --- a/libobs/obs-hotkey.h +++ b/libobs/obs-hotkey.h @@ -124,6 +124,9 @@ EXPORT void obs_hotkeys_set_audio_hotkeys_translations( const char *mute, const char *unmute, const char *push_to_mute, const char *push_to_talk); +EXPORT void obs_hotkeys_set_sceneitem_hotkeys_translations( + const char *show, const char *hide); + /* registering hotkeys (giving hotkeys a name and a function) */ typedef void (*obs_hotkey_func)(void *data, diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index dbdd34064..a95295c12 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -303,6 +303,8 @@ struct obs_core_hotkeys { char *unmute; char *push_to_mute; char *push_to_talk; + char *sceneitem_show; + char *sceneitem_hide; }; struct obs_core { diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 0984e7aab..d6652dc31 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -555,6 +555,82 @@ void obs_scene_enum_items(obs_scene_t *scene, pthread_mutex_unlock(&scene->mutex); } +static obs_sceneitem_t *sceneitem_get_ref(obs_sceneitem_t *si) +{ + long owners = si->ref; + while (owners > 0) { + if (os_atomic_compare_swap_long(&si->ref, owners, owners + 1)) + return si; + + owners = si->ref; + } + return NULL; +} + +static bool hotkey_show_sceneitem(void *data, obs_hotkey_pair_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + obs_sceneitem_t *si = sceneitem_get_ref(data); + if (pressed && si && !si->visible) { + obs_sceneitem_set_visible(si, true); + obs_sceneitem_release(si); + return true; + } + + obs_sceneitem_release(si); + return false; +} + +static bool hotkey_hide_sceneitem(void *data, obs_hotkey_pair_id id, + obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + obs_sceneitem_t *si = sceneitem_get_ref(data); + if (pressed && si && si->visible) { + obs_sceneitem_set_visible(si, false); + obs_sceneitem_release(si); + return true; + } + + obs_sceneitem_release(si); + return false; +} + +static void init_hotkeys(obs_scene_t *scene, obs_sceneitem_t *item, + const char *name) +{ + struct dstr show = {0}; + struct dstr hide = {0}; + struct dstr show_desc = {0}; + struct dstr hide_desc = {0}; + + dstr_copy(&show, "libobs.show_scene_item.%1"); + dstr_replace(&show, "%1", name); + dstr_copy(&hide, "libobs.hide_scene_item.%1"); + dstr_replace(&hide, "%1", name); + + dstr_copy(&show_desc, obs->hotkeys.sceneitem_show); + dstr_replace(&show_desc, "%1", name); + dstr_copy(&hide_desc, obs->hotkeys.sceneitem_hide); + dstr_replace(&hide_desc, "%1", name); + + item->toggle_visibility = obs_hotkey_pair_register_source(scene->source, + show.array, show_desc.array, + hide.array, hide_desc.array, + hotkey_show_sceneitem, hotkey_hide_sceneitem, + item, item); + + dstr_free(&show); + dstr_free(&hide); + dstr_free(&show_desc); + dstr_free(&hide_desc); +} + obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) { struct obs_scene_item *last; @@ -602,6 +678,8 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) pthread_mutex_unlock(&scene->mutex); + init_hotkeys(scene, item, obs_source_get_name(source)); + calldata_set_ptr(¶ms, "scene", scene); calldata_set_ptr(¶ms, "item", item); signal_handler_signal(scene->source->context.signals, "item_add", @@ -614,6 +692,7 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) static void obs_sceneitem_destroy(obs_sceneitem_t *item) { if (item) { + obs_hotkey_pair_unregister(item->toggle_visibility); if (item->source) obs_source_release(item->source); bfree(item); diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index f827919da..433d7dea3 100644 --- a/libobs/obs-scene.h +++ b/libobs/obs-scene.h @@ -49,6 +49,8 @@ struct obs_scene_item { uint32_t bounds_align; struct vec2 bounds; + obs_hotkey_pair_id toggle_visibility; + /* would do **prev_next, but not really great for reordering */ struct obs_scene_item *prev; struct obs_scene_item *next; diff --git a/libobs/obs.c b/libobs/obs.c index eede4f4f7..e96399d38 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -646,6 +646,8 @@ static inline bool obs_init_hotkeys(void) hotkeys->unmute = bstrdup("Unmute"); hotkeys->push_to_mute = bstrdup("Push-to-mute"); hotkeys->push_to_talk = bstrdup("Push-to-talk"); + hotkeys->sceneitem_show = bstrdup("Show '%1'"); + hotkeys->sceneitem_hide = bstrdup("Hide '%1'"); if (!obs_hotkeys_platform_init(hotkeys)) return false; @@ -695,6 +697,8 @@ static inline void obs_free_hotkeys(void) bfree(hotkeys->unmute); bfree(hotkeys->push_to_mute); bfree(hotkeys->push_to_talk); + bfree(hotkeys->sceneitem_show); + bfree(hotkeys->sceneitem_hide); obs_hotkey_name_map_free();