提交 6c535513 编写于 作者: J jp9000

Merge branch 'global-hotkeys'

......@@ -69,8 +69,23 @@ elseif(APPLE)
mark_as_advanced(COCOA)
include_directories(${COCOA})
find_library(APPKIT AppKit)
mark_as_advanced(APPKIT)
include_directories(${APPKIT})
find_library(IOKIT IOKit)
mark_as_advanced(IOKIT)
include_directories(${IOKIT})
find_library(CARBON Carbon)
mark_as_advanced(CARBON)
include_directories(${CARBON})
set(libobs_PLATFORM_DEPS
${COCOA})
${COCOA}
${APPKIT}
${IOKIT}
${CARBON})
elseif(UNIX)
set(libobs_PLATFORM_SOURCES
obs-nix.c
......@@ -216,6 +231,8 @@ set(libobs_libobs_SOURCES
obs.c
obs-properties.c
obs-data.c
obs-hotkey.c
obs-hotkey-name-map.c
obs-module.c
obs-display.c
obs-view.c
......@@ -233,6 +250,8 @@ set(libobs_libobs_HEADERS
obs-properties.h
obs-data.h
obs-interaction.h
obs-hotkey.h
obs-hotkeys.h
obs-module.h
obs-scene.h
obs-source.h
......
此差异已折叠。
......@@ -37,12 +37,13 @@ const char *obs_encoder_get_display_name(const char *id)
}
static bool init_encoder(struct obs_encoder *encoder, const char *name,
obs_data_t *settings)
obs_data_t *settings, obs_data_t *hotkey_data)
{
pthread_mutex_init_value(&encoder->callbacks_mutex);
pthread_mutex_init_value(&encoder->outputs_mutex);
if (!obs_context_data_init(&encoder->context, settings, name))
if (!obs_context_data_init(&encoder->context, settings, name,
hotkey_data))
return false;
if (pthread_mutex_init(&encoder->callbacks_mutex, NULL) != 0)
return false;
......@@ -57,7 +58,7 @@ static bool init_encoder(struct obs_encoder *encoder, const char *name,
static struct obs_encoder *create_encoder(const char *id,
enum obs_encoder_type type, const char *name,
obs_data_t *settings, size_t mixer_idx)
obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data)
{
struct obs_encoder *encoder;
struct obs_encoder_info *ei = find_encoder(id);
......@@ -70,7 +71,7 @@ static struct obs_encoder *create_encoder(const char *id,
encoder->info = *ei;
encoder->mixer_idx = mixer_idx;
success = init_encoder(encoder, name, settings);
success = init_encoder(encoder, name, settings, hotkey_data);
if (!success) {
obs_encoder_destroy(encoder);
encoder = NULL;
......@@ -88,17 +89,19 @@ static struct obs_encoder *create_encoder(const char *id,
}
obs_encoder_t *obs_video_encoder_create(const char *id, const char *name,
obs_data_t *settings)
obs_data_t *settings, obs_data_t *hotkey_data)
{
if (!name || !id) return NULL;
return create_encoder(id, OBS_ENCODER_VIDEO, name, settings, 0);
return create_encoder(id, OBS_ENCODER_VIDEO, name, settings, 0,
hotkey_data);
}
obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name,
obs_data_t *settings, size_t mixer_idx)
obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data)
{
if (!name || !id) return NULL;
return create_encoder(id, OBS_ENCODER_AUDIO, name, settings, mixer_idx);
return create_encoder(id, OBS_ENCODER_AUDIO, name, settings, mixer_idx,
hotkey_data);
}
static void receive_video(void *param, struct video_data *frame);
......
/******************************************************************************
Copyright (C) 2014 by Ruwen Hahn <palana@stunned.de>
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 <http://www.gnu.org/licenses/>.
******************************************************************************/
#include <string.h>
#include <assert.h>
#include <util/bmem.h>
#include <util/c99defs.h>
#include <util/darray.h>
#include "obs-internal.h"
struct obs_hotkey_name_map_edge;
struct obs_hotkey_name_map_node;
struct obs_hotkey_name_map;
typedef struct obs_hotkey_name_map_edge obs_hotkey_name_map_edge_t;
typedef struct obs_hotkey_name_map_node obs_hotkey_name_map_node_t;
typedef struct obs_hotkey_name_map obs_hotkey_name_map_t;
struct obs_hotkey_name_map_node {
bool is_leaf;
union {
int val;
DARRAY(obs_hotkey_name_map_edge_t) children;
};
};
struct obs_hotkey_name_map {
obs_hotkey_name_map_node_t root;
obs_hotkey_name_map_node_t *leaves;
size_t num_leaves;
size_t next_leaf;
};
struct obs_hotkey_name_map_edge_prefix {
uint8_t prefix_len;
char *prefix;
};
#define NAME_MAP_COMPRESS_LENGTH \
(sizeof(struct obs_hotkey_name_map_edge_prefix) - sizeof(uint8_t))
struct obs_hotkey_name_map_edge {
union {
struct {
uint8_t prefix_len;
char *prefix;
};
struct {
uint8_t compressed_len;
char compressed_prefix[NAME_MAP_COMPRESS_LENGTH];
};
};
struct obs_hotkey_name_map_node *node;
};
static inline obs_hotkey_name_map_node_t *new_node(void)
{
return bzalloc(sizeof(obs_hotkey_name_map_node_t));
}
static inline obs_hotkey_name_map_node_t *new_leaf(void)
{
obs_hotkey_name_map_t *name_map = obs->hotkeys.name_map;
obs_hotkey_name_map_node_t *node =
&name_map->leaves[name_map->next_leaf];
name_map->next_leaf += 1;
node->is_leaf = true;
return node;
}
static inline char *get_prefix(obs_hotkey_name_map_edge_t *e)
{
return e->prefix_len >= NAME_MAP_COMPRESS_LENGTH ?
e->prefix : e->compressed_prefix;
}
static void set_prefix(obs_hotkey_name_map_edge_t *e, const char *prefix,
size_t l)
{
assert(e->prefix_len == 0);
e->compressed_len = (uint8_t)l;
if (l < NAME_MAP_COMPRESS_LENGTH)
strncpy(e->compressed_prefix, prefix, l);
else
e->prefix = bstrdup_n(prefix, l);
}
static obs_hotkey_name_map_edge_t *add_leaf(obs_hotkey_name_map_node_t *node,
const char *key, size_t l, int v)
{
obs_hotkey_name_map_edge_t *e = da_push_back_new(node->children);
set_prefix(e, key, l);
e->node = new_leaf();
e->node->val = v;
return e;
}
static void shrink_prefix(obs_hotkey_name_map_edge_t *e, size_t l)
{
bool old_comp = e->prefix_len < NAME_MAP_COMPRESS_LENGTH;
bool new_comp = l < NAME_MAP_COMPRESS_LENGTH;
char *str = get_prefix(e);
e->prefix_len = (uint8_t)l;
if (get_prefix(e) != str)
strncpy(get_prefix(e), str, l);
else
str[l] = 0;
if (!old_comp && new_comp)
bfree(str);
}
static void connect(obs_hotkey_name_map_edge_t *e,
obs_hotkey_name_map_node_t *n)
{
e->node = n;
}
static void reduce_edge(obs_hotkey_name_map_edge_t *e, const char *key,
size_t l, int v)
{
const char *str = get_prefix(e), *str_ = key;
size_t common_length = 0;
while (*str == *str_) {
common_length += 1;
str += 1;
str_ += 1;
}
obs_hotkey_name_map_node_t *new_node_ = new_node();
obs_hotkey_name_map_edge_t *tail =
da_push_back_new(new_node_->children);
connect(tail, e->node);
set_prefix(tail, str, e->prefix_len - common_length);
add_leaf(new_node_, str_, l - common_length, v);
connect(e, new_node_);
shrink_prefix(e, common_length);
}
enum obs_hotkey_name_map_edge_compare_result {
RES_MATCHES,
RES_NO_MATCH,
RES_COMMON_PREFIX,
RES_PREFIX_MATCHES,
};
static enum obs_hotkey_name_map_edge_compare_result compare_prefix(
obs_hotkey_name_map_edge_t *edge, const char *key, size_t l)
{
uint8_t pref_len = edge->prefix_len;
const char *str = get_prefix(edge);
size_t i = 0;
for (; i < l && i < pref_len; i++)
if (str[i] != key[i])
break;
if (i != 0 && pref_len == i)
return l == i ? RES_MATCHES : RES_PREFIX_MATCHES;
if (i != 0)
return pref_len == i ? RES_PREFIX_MATCHES : RES_COMMON_PREFIX;
return RES_NO_MATCH;
}
static void insert(obs_hotkey_name_map_edge_t *edge,
obs_hotkey_name_map_node_t *node,
const char *key, size_t l, int v)
{
if (node->is_leaf && l > 0) {
obs_hotkey_name_map_node_t *new_node_ = new_node();
connect(edge, new_node_);
obs_hotkey_name_map_edge_t *edge =
da_push_back_new(new_node_->children);
connect(edge, node);
add_leaf(new_node_, key, l, v);
return;
}
if (node->is_leaf && l == 0) {
node->val = v;
return;
}
for (size_t i = 0; i < node->children.num; i++) {
obs_hotkey_name_map_edge_t *e = &node->children.array[i];
switch (compare_prefix(e, key, l)) {
case RES_NO_MATCH:
continue;
case RES_MATCHES:
case RES_PREFIX_MATCHES:
insert(e, e->node, key + e->prefix_len,
l - e->prefix_len, v);
return;
case RES_COMMON_PREFIX:
reduce_edge(e, key, l, v);
return;
}
}
add_leaf(node, key, l, v);
}
static void obs_hotkey_name_map_insert(obs_hotkey_name_map_t *trie,
const char *key, int v)
{
if (!trie || !key)
return;
insert(NULL, &trie->root, key, strlen(key), v);
}
static bool obs_hotkey_name_map_lookup(obs_hotkey_name_map_t *trie,
const char *key, int *v)
{
if (!trie || !key)
return false;
size_t len = strlen(key);
obs_hotkey_name_map_node_t *n = &trie->root;
size_t i = 0;
for (; i < n->children.num;) {
obs_hotkey_name_map_edge_t *e = &n->children.array[i];
switch (compare_prefix(e, key, len)) {
case RES_NO_MATCH:
i++;
continue;
case RES_COMMON_PREFIX:
return false;
case RES_PREFIX_MATCHES:
key += e->prefix_len;
len -= e->prefix_len;
n = e->node;
i = 0;
continue;
case RES_MATCHES:
n = e->node;
if (!n->is_leaf) {
for (size_t j = 0; j < n->children.num; j++) {
if (n->children.array[j].prefix_len)
continue;
if (v) *v =
n->children.array[j].node->val;
return true;
}
return false;
}
if (v) *v = n->val;
return true;
}
}
return false;
}
static void show_node(obs_hotkey_name_map_node_t *node, int in)
{
if (node->is_leaf) {
printf(": % 3d\n", node->val);
return;
}
printf("\n");
for (int i = 0; i < in; i += 2)
printf("| ");
printf("%zu:\n", node->children.num);
for (size_t i = 0; i < node->children.num; i++) {
for (int i = 0; i < in; i += 2)
printf("| ");
printf("\\ ");
obs_hotkey_name_map_edge_t *e = &node->children.array[i];
printf("%s", get_prefix(e));
show_node(e->node, in+2);
}
}
void trie_print_size(obs_hotkey_name_map_t *trie)
{
show_node(&trie->root, 0);
}
static const char* obs_key_names[] = {
#define OBS_HOTKEY(x) #x,
#include "obs-hotkeys.h"
#undef OBS_HOTKEY
};
const char* obs_key_to_name(obs_key_t key)
{
if (key >= OBS_KEY_LAST_VALUE) {
blog(LOG_ERROR, "obs-hotkey.c: queried unknown key "
"with code %d", (int)key);
return "";
}
return obs_key_names[key];
}
static obs_key_t obs_key_from_name_fallback(const char *name)
{
#define OBS_HOTKEY(x) if (strcmp(#x, name) == 0) return x;
#include "obs-hotkeys.h"
#undef OBS_HOTKEY
return OBS_KEY_NONE;
}
static void init_name_map(void)
{
obs->hotkeys.name_map = bzalloc(sizeof(struct obs_hotkey_name_map));
obs_hotkey_name_map_t *name_map = obs->hotkeys.name_map;
#define OBS_HOTKEY(x) name_map->num_leaves += 1;
#include "obs-hotkeys.h"
#undef OBS_HOTKEY
size_t size = sizeof(obs_hotkey_name_map_node_t) * name_map->num_leaves;
name_map->leaves = bzalloc(size);
#define OBS_HOTKEY(x) obs_hotkey_name_map_insert(name_map, #x, x);
#include "obs-hotkeys.h"
#undef OBS_HOTKEY
}
obs_key_t obs_key_from_name(const char *name)
{
if (!obs)
return obs_key_from_name_fallback(name);
if (pthread_once(&obs->hotkeys.name_map_init_token, init_name_map))
return obs_key_from_name_fallback(name);
int v = 0;
if (obs_hotkey_name_map_lookup(obs->hotkeys.name_map, name, &v))
return v;
return OBS_KEY_NONE;
}
static void free_node(obs_hotkey_name_map_node_t *node, bool release);
static void free_edge(obs_hotkey_name_map_edge_t *edge)
{
free_node(edge->node, true);
if (edge->prefix_len < NAME_MAP_COMPRESS_LENGTH)
return;
bfree(get_prefix(edge));
}
static void free_node(obs_hotkey_name_map_node_t *node, bool release)
{
if (!node->is_leaf) {
for (size_t i = 0; i < node->children.num; i++)
free_edge(&node->children.array[i]);
da_free(node->children);
}
if (release && !node->is_leaf) bfree(node);
}
void obs_hotkey_name_map_free(void)
{
if (!obs || !obs->hotkeys.name_map)
return;
free_node(&obs->hotkeys.name_map->root, false);
bfree(obs->hotkeys.name_map->leaves);
bfree(obs->hotkeys.name_map);
}
此差异已折叠。
/******************************************************************************
Copyright (C) 2014-2015 by Ruwen Hahn <palana@stunned.de>
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 <http://www.gnu.org/licenses/>.
******************************************************************************/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef size_t obs_hotkey_id;
#define OBS_INVALID_HOTKEY_ID (~(obs_hotkey_id)0)
typedef size_t obs_hotkey_pair_id;
#define OBS_INVALID_HOTKEY_PAIR_ID (~(obs_hotkey_pair_id)0)
enum obs_key {
#define OBS_HOTKEY(x) x,
#include "obs-hotkeys.h"
#undef OBS_HOTKEY
OBS_KEY_LAST_VALUE //not an actual key
};
typedef enum obs_key obs_key_t;
struct obs_key_combination {
uint32_t modifiers;
obs_key_t key;
};
typedef struct obs_key_combination obs_key_combination_t;
typedef struct obs_hotkey obs_hotkey_t;
typedef struct obs_hotkey_binding obs_hotkey_binding_t;
enum obs_hotkey_registerer_type {
OBS_HOTKEY_REGISTERER_FRONTEND,
OBS_HOTKEY_REGISTERER_SOURCE,
OBS_HOTKEY_REGISTERER_OUTPUT,
OBS_HOTKEY_REGISTERER_ENCODER,
OBS_HOTKEY_REGISTERER_SERVICE,
};
typedef enum obs_hotkey_registerer_type obs_hotkey_registerer_t;
EXPORT obs_hotkey_id obs_hotkey_get_id(const obs_hotkey_t *key);
EXPORT const char *obs_hotkey_get_name(const obs_hotkey_t *key);
EXPORT const char *obs_hotkey_get_description(const obs_hotkey_t *key);
EXPORT obs_hotkey_registerer_t obs_hotkey_get_registerer_type(
const obs_hotkey_t *key);
EXPORT void *obs_hotkey_get_registerer(const obs_hotkey_t *key);
EXPORT obs_hotkey_id obs_hotkey_get_pair_partner_id(const obs_hotkey_t *key);
EXPORT obs_key_combination_t obs_hotkey_binding_get_key_combination(
obs_hotkey_binding_t *binding);
EXPORT obs_hotkey_id obs_hotkey_binding_get_hotkey_id(
obs_hotkey_binding_t *binding);
EXPORT obs_hotkey_t *obs_hotkey_binding_get_hotkey(
obs_hotkey_binding_t *binding);
struct obs_hotkeys_translations {
const char *insert;
const char *del;
const char *home;
const char *end;
const char *page_up;
const char *page_down;
const char *num_lock;
const char *scroll_lock;
const char *caps_lock;
const char *backspace;
const char *tab;
const char *print;
const char *pause;
const char *left;
const char *right;
const char *up;
const char *down;
const char *shift;
const char *alt;
const char *control;
const char *meta; /* windows/super key */
const char *menu;
const char *space;
const char *numpad_num; /* For example, "Numpad %1" */
const char *numpad_divide;
const char *numpad_multiply;
const char *numpad_minus;
const char *numpad_plus;
const char *numpad_decimal;
const char *apple_keypad_num; /* For example, "%1 (Keypad)" */
const char *apple_keypad_divide;
const char *apple_keypad_multiply;
const char *apple_keypad_minus;
const char *apple_keypad_plus;
const char *apple_keypad_decimal;
const char *apple_keypad_equal;
const char *mouse_num; /* For example, "Mouse %1" */
};
/* This function is an optional way to provide translations for specific keys
* that may not have translations. If the operating system can provide
* translations for these keys, it will use the operating system's translation
* over these translations. If no translations are specified, it will use
* the default english translations for that specific operating system. */
EXPORT void obs_hotkeys_set_translations_s(
struct obs_hotkeys_translations *translations, size_t size);
#define obs_hotkeys_set_translations(translations) \
obs_hotkeys_set_translations_s(translations, \
sizeof(struct obs_hotkeys_translations))
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,
obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed);
EXPORT obs_hotkey_id obs_hotkey_register_frontend(const char *name,
const char *description, obs_hotkey_func func, void *data);
EXPORT obs_hotkey_id obs_hotkey_register_encoder(obs_encoder_t *encoder,
const char *name, const char *description,
obs_hotkey_func func, void *data);
EXPORT obs_hotkey_id obs_hotkey_register_output(obs_output_t *output,
const char *name, const char *description,
obs_hotkey_func func, void *data);
EXPORT obs_hotkey_id obs_hotkey_register_service(obs_service_t *service,
const char *name, const char *description,
obs_hotkey_func func, void *data);
EXPORT obs_hotkey_id obs_hotkey_register_source(obs_source_t *source,
const char *name, const char *description,
obs_hotkey_func func, void *data);
typedef bool (*obs_hotkey_active_func)(void *data,
obs_hotkey_pair_id id, obs_hotkey_t *hotkey, bool pressed);
EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_frontend(
const char *name0, const char *description0,
const char *name1, const char *description1,
obs_hotkey_active_func func0, obs_hotkey_active_func func1,
void *data0, void *data1);
EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_encoder(
obs_encoder_t *encoder,
const char *name0, const char *description0,
const char *name1, const char *description1,
obs_hotkey_active_func func0, obs_hotkey_active_func func1,
void *data0, void *data1);
EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_output(
obs_output_t *output,
const char *name0, const char *description0,
const char *name1, const char *description1,
obs_hotkey_active_func func0, obs_hotkey_active_func func1,
void *data0, void *data1);
EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_service(
obs_service_t *service,
const char *name0, const char *description0,
const char *name1, const char *description1,
obs_hotkey_active_func func0, obs_hotkey_active_func func1,
void *data0, void *data1);
EXPORT obs_hotkey_pair_id obs_hotkey_pair_register_source(
obs_source_t *source,
const char *name0, const char *description0,
const char *name1, const char *description1,
obs_hotkey_active_func func0, obs_hotkey_active_func func1,
void *data0, void *data1);
EXPORT void obs_hotkey_unregister(obs_hotkey_id id);
EXPORT void obs_hotkey_pair_unregister(obs_hotkey_pair_id id);
/* loading hotkeys (associating a hotkey with a physical key and modifiers) */
EXPORT void obs_hotkey_load_bindings(obs_hotkey_id id,
obs_key_combination_t *combinations, size_t num);
EXPORT void obs_hotkey_load(obs_hotkey_id id, obs_data_array_t *data);
EXPORT void obs_hotkeys_load_encoder(obs_encoder_t *encoder,
obs_data_t *hotkeys);
EXPORT void obs_hotkeys_load_output(obs_output_t *output, obs_data_t *hotkeys);
EXPORT void obs_hotkeys_load_service(obs_service_t *service,
obs_data_t *hotkeys);
EXPORT void obs_hotkeys_load_source(obs_source_t *source, obs_data_t *hotkeys);
EXPORT void obs_hotkey_pair_load(obs_hotkey_pair_id id, obs_data_array_t *data0,
obs_data_array_t *data1);
EXPORT obs_data_array_t *obs_hotkey_save(obs_hotkey_id id);
EXPORT obs_data_t *obs_hotkeys_save_encoder(obs_encoder_t *encoder);
EXPORT obs_data_t *obs_hotkeys_save_output(obs_output_t *output);
EXPORT obs_data_t *obs_hotkeys_save_service(obs_service_t *service);
EXPORT obs_data_t *obs_hotkeys_save_source(obs_source_t *source);
/* enumerating hotkeys */
typedef bool (*obs_hotkey_enum_func)(void *data,
obs_hotkey_id id, obs_hotkey_t *key);
EXPORT void obs_enum_hotkeys(obs_hotkey_enum_func func, void *data);
/* enumerating bindings */
typedef bool (*obs_hotkey_binding_enum_func)(void *data,
size_t idx, obs_hotkey_binding_t* binding);
EXPORT void obs_enum_hotkey_bindings(obs_hotkey_binding_enum_func func,
void *data);
/* hotkey event control */
EXPORT void obs_hotkey_inject_event(obs_key_combination_t hotkey, bool pressed);
EXPORT void obs_hotkey_enable_background_press(bool enable);
EXPORT void obs_hotkey_enable_strict_modifiers(bool enable);
/* hotkey callback routing (trigger callbacks through e.g. a UI thread) */
typedef void (*obs_hotkey_callback_router_func)(void *data,
obs_hotkey_id id, bool pressed);
EXPORT void obs_hotkey_set_callback_routing_func(obs_hotkey_callback_router_func
func, void *data);
EXPORT void obs_hotkey_trigger_routed_callback(obs_hotkey_id id, bool pressed);
/* hotkey callbacks won't be processed if callback rerouting is enabled and no
* router func is set */
EXPORT void obs_hotkey_enable_callback_rerouting(bool enable);
/* misc */
typedef void (*obs_hotkey_atomic_update_func)(void *);
EXPORT void obs_hotkey_update_atomic(obs_hotkey_atomic_update_func func,
void *data);
struct dstr;
EXPORT void obs_key_to_str(obs_key_t key, struct dstr *str);
EXPORT void obs_key_combination_to_str(obs_key_combination_t key,
struct dstr *str);
EXPORT obs_key_t obs_key_from_virtual_key(int code);
EXPORT int obs_key_to_virtual_key(obs_key_t key);
EXPORT const char *obs_key_to_name(obs_key_t key);
EXPORT obs_key_t obs_key_from_name(const char *name);
inline bool obs_key_combination_is_empty(obs_key_combination_t combo)
{
return !combo.modifiers && combo.key == OBS_KEY_NONE;
}
#ifdef __cplusplus
}
#endif
OBS_HOTKEY(OBS_KEY_NONE)
OBS_HOTKEY(OBS_KEY_RETURN)
OBS_HOTKEY(OBS_KEY_ENTER)
OBS_HOTKEY(OBS_KEY_ESCAPE)
OBS_HOTKEY(OBS_KEY_TAB)
OBS_HOTKEY(OBS_KEY_BACKTAB)
OBS_HOTKEY(OBS_KEY_BACKSPACE)
OBS_HOTKEY(OBS_KEY_INSERT)
OBS_HOTKEY(OBS_KEY_DELETE)
OBS_HOTKEY(OBS_KEY_PAUSE)
OBS_HOTKEY(OBS_KEY_PRINT)
OBS_HOTKEY(OBS_KEY_SYSREQ)
OBS_HOTKEY(OBS_KEY_CLEAR)
OBS_HOTKEY(OBS_KEY_HOME)
OBS_HOTKEY(OBS_KEY_END)
OBS_HOTKEY(OBS_KEY_LEFT)
OBS_HOTKEY(OBS_KEY_UP)
OBS_HOTKEY(OBS_KEY_RIGHT)
OBS_HOTKEY(OBS_KEY_DOWN)
OBS_HOTKEY(OBS_KEY_PAGEUP)
OBS_HOTKEY(OBS_KEY_PAGEDOWN)
OBS_HOTKEY(OBS_KEY_SHIFT)
OBS_HOTKEY(OBS_KEY_CONTROL)
OBS_HOTKEY(OBS_KEY_META)
OBS_HOTKEY(OBS_KEY_ALT)
OBS_HOTKEY(OBS_KEY_ALTGR)
OBS_HOTKEY(OBS_KEY_CAPSLOCK)
OBS_HOTKEY(OBS_KEY_NUMLOCK)
OBS_HOTKEY(OBS_KEY_SCROLLLOCK)
OBS_HOTKEY(OBS_KEY_F1)
OBS_HOTKEY(OBS_KEY_F2)
OBS_HOTKEY(OBS_KEY_F3)
OBS_HOTKEY(OBS_KEY_F4)
OBS_HOTKEY(OBS_KEY_F5)
OBS_HOTKEY(OBS_KEY_F6)
OBS_HOTKEY(OBS_KEY_F7)
OBS_HOTKEY(OBS_KEY_F8)
OBS_HOTKEY(OBS_KEY_F9)
OBS_HOTKEY(OBS_KEY_F10)
OBS_HOTKEY(OBS_KEY_F11)
OBS_HOTKEY(OBS_KEY_F12)
OBS_HOTKEY(OBS_KEY_F13)
OBS_HOTKEY(OBS_KEY_F14)
OBS_HOTKEY(OBS_KEY_F15)
OBS_HOTKEY(OBS_KEY_F16)
OBS_HOTKEY(OBS_KEY_F17)
OBS_HOTKEY(OBS_KEY_F18)
OBS_HOTKEY(OBS_KEY_F19)
OBS_HOTKEY(OBS_KEY_F20)
OBS_HOTKEY(OBS_KEY_F21)
OBS_HOTKEY(OBS_KEY_F22)
OBS_HOTKEY(OBS_KEY_F23)
OBS_HOTKEY(OBS_KEY_F24)
OBS_HOTKEY(OBS_KEY_F25)
OBS_HOTKEY(OBS_KEY_F26)
OBS_HOTKEY(OBS_KEY_F27)
OBS_HOTKEY(OBS_KEY_F28)
OBS_HOTKEY(OBS_KEY_F29)
OBS_HOTKEY(OBS_KEY_F30)
OBS_HOTKEY(OBS_KEY_F31)
OBS_HOTKEY(OBS_KEY_F32)
OBS_HOTKEY(OBS_KEY_F33)
OBS_HOTKEY(OBS_KEY_F34)
OBS_HOTKEY(OBS_KEY_F35)
OBS_HOTKEY(OBS_KEY_MENU)
OBS_HOTKEY(OBS_KEY_HYPER_L)
OBS_HOTKEY(OBS_KEY_HYPER_R)
OBS_HOTKEY(OBS_KEY_HELP)
OBS_HOTKEY(OBS_KEY_DIRECTION_L)
OBS_HOTKEY(OBS_KEY_DIRECTION_R)
OBS_HOTKEY(OBS_KEY_SPACE)
OBS_HOTKEY(OBS_KEY_EXCLAM)
OBS_HOTKEY(OBS_KEY_QUOTEDBL)
OBS_HOTKEY(OBS_KEY_NUMBERSIGN)
OBS_HOTKEY(OBS_KEY_DOLLAR)
OBS_HOTKEY(OBS_KEY_PERCENT)
OBS_HOTKEY(OBS_KEY_AMPERSAND)
OBS_HOTKEY(OBS_KEY_APOSTROPHE)
OBS_HOTKEY(OBS_KEY_PARENLEFT)
OBS_HOTKEY(OBS_KEY_PARENRIGHT)
OBS_HOTKEY(OBS_KEY_ASTERISK)
OBS_HOTKEY(OBS_KEY_PLUS)
OBS_HOTKEY(OBS_KEY_COMMA)
OBS_HOTKEY(OBS_KEY_MINUS)
OBS_HOTKEY(OBS_KEY_PERIOD)
OBS_HOTKEY(OBS_KEY_SLASH)
OBS_HOTKEY(OBS_KEY_0)
OBS_HOTKEY(OBS_KEY_1)
OBS_HOTKEY(OBS_KEY_2)
OBS_HOTKEY(OBS_KEY_3)
OBS_HOTKEY(OBS_KEY_4)
OBS_HOTKEY(OBS_KEY_5)
OBS_HOTKEY(OBS_KEY_6)
OBS_HOTKEY(OBS_KEY_7)
OBS_HOTKEY(OBS_KEY_8)
OBS_HOTKEY(OBS_KEY_9)
OBS_HOTKEY(OBS_KEY_NUMEQUAL)
OBS_HOTKEY(OBS_KEY_NUMASTERISK)
OBS_HOTKEY(OBS_KEY_NUMPLUS)
OBS_HOTKEY(OBS_KEY_NUMCOMMA)
OBS_HOTKEY(OBS_KEY_NUMMINUS)
OBS_HOTKEY(OBS_KEY_NUMPERIOD)
OBS_HOTKEY(OBS_KEY_NUMSLASH)
OBS_HOTKEY(OBS_KEY_NUM0)
OBS_HOTKEY(OBS_KEY_NUM1)
OBS_HOTKEY(OBS_KEY_NUM2)
OBS_HOTKEY(OBS_KEY_NUM3)
OBS_HOTKEY(OBS_KEY_NUM4)
OBS_HOTKEY(OBS_KEY_NUM5)
OBS_HOTKEY(OBS_KEY_NUM6)
OBS_HOTKEY(OBS_KEY_NUM7)
OBS_HOTKEY(OBS_KEY_NUM8)
OBS_HOTKEY(OBS_KEY_NUM9)
OBS_HOTKEY(OBS_KEY_COLON)
OBS_HOTKEY(OBS_KEY_SEMICOLON)
OBS_HOTKEY(OBS_KEY_QUOTE)
OBS_HOTKEY(OBS_KEY_LESS)
OBS_HOTKEY(OBS_KEY_EQUAL)
OBS_HOTKEY(OBS_KEY_GREATER)
OBS_HOTKEY(OBS_KEY_QUESTION)
OBS_HOTKEY(OBS_KEY_AT)
OBS_HOTKEY(OBS_KEY_A)
OBS_HOTKEY(OBS_KEY_B)
OBS_HOTKEY(OBS_KEY_C)
OBS_HOTKEY(OBS_KEY_D)
OBS_HOTKEY(OBS_KEY_E)
OBS_HOTKEY(OBS_KEY_F)
OBS_HOTKEY(OBS_KEY_G)
OBS_HOTKEY(OBS_KEY_H)
OBS_HOTKEY(OBS_KEY_I)
OBS_HOTKEY(OBS_KEY_J)
OBS_HOTKEY(OBS_KEY_K)
OBS_HOTKEY(OBS_KEY_L)
OBS_HOTKEY(OBS_KEY_M)
OBS_HOTKEY(OBS_KEY_N)
OBS_HOTKEY(OBS_KEY_O)
OBS_HOTKEY(OBS_KEY_P)
OBS_HOTKEY(OBS_KEY_Q)
OBS_HOTKEY(OBS_KEY_R)
OBS_HOTKEY(OBS_KEY_S)
OBS_HOTKEY(OBS_KEY_T)
OBS_HOTKEY(OBS_KEY_U)
OBS_HOTKEY(OBS_KEY_V)
OBS_HOTKEY(OBS_KEY_W)
OBS_HOTKEY(OBS_KEY_X)
OBS_HOTKEY(OBS_KEY_Y)
OBS_HOTKEY(OBS_KEY_Z)
OBS_HOTKEY(OBS_KEY_BRACKETLEFT)
OBS_HOTKEY(OBS_KEY_BACKSLASH)
OBS_HOTKEY(OBS_KEY_BRACKETRIGHT)
OBS_HOTKEY(OBS_KEY_ASCIICIRCUM)
OBS_HOTKEY(OBS_KEY_UNDERSCORE)
OBS_HOTKEY(OBS_KEY_QUOTELEFT)
OBS_HOTKEY(OBS_KEY_BRACELEFT)
OBS_HOTKEY(OBS_KEY_BAR)
OBS_HOTKEY(OBS_KEY_BRACERIGHT)
OBS_HOTKEY(OBS_KEY_ASCIITILDE)
OBS_HOTKEY(OBS_KEY_NOBREAKSPACE)
OBS_HOTKEY(OBS_KEY_EXCLAMDOWN)
OBS_HOTKEY(OBS_KEY_CENT)
OBS_HOTKEY(OBS_KEY_STERLING)
OBS_HOTKEY(OBS_KEY_CURRENCY)
OBS_HOTKEY(OBS_KEY_YEN)
OBS_HOTKEY(OBS_KEY_BROKENBAR)
OBS_HOTKEY(OBS_KEY_SECTION)
OBS_HOTKEY(OBS_KEY_DIAERESIS)
OBS_HOTKEY(OBS_KEY_COPYRIGHT)
OBS_HOTKEY(OBS_KEY_ORDFEMININE)
OBS_HOTKEY(OBS_KEY_GUILLEMOTLEFT)
OBS_HOTKEY(OBS_KEY_NOTSIGN)
OBS_HOTKEY(OBS_KEY_HYPHEN)
OBS_HOTKEY(OBS_KEY_REGISTERED)
OBS_HOTKEY(OBS_KEY_MACRON)
OBS_HOTKEY(OBS_KEY_DEGREE)
OBS_HOTKEY(OBS_KEY_PLUSMINUS)
OBS_HOTKEY(OBS_KEY_TWOSUPERIOR)
OBS_HOTKEY(OBS_KEY_THREESUPERIOR)
OBS_HOTKEY(OBS_KEY_ACUTE)
OBS_HOTKEY(OBS_KEY_MU)
OBS_HOTKEY(OBS_KEY_PARAGRAPH)
OBS_HOTKEY(OBS_KEY_PERIODCENTERED)
OBS_HOTKEY(OBS_KEY_CEDILLA)
OBS_HOTKEY(OBS_KEY_ONESUPERIOR)
OBS_HOTKEY(OBS_KEY_MASCULINE)
OBS_HOTKEY(OBS_KEY_GUILLEMOTRIGHT)
OBS_HOTKEY(OBS_KEY_ONEQUARTER)
OBS_HOTKEY(OBS_KEY_ONEHALF)
OBS_HOTKEY(OBS_KEY_THREEQUARTERS)
OBS_HOTKEY(OBS_KEY_QUESTIONDOWN)
OBS_HOTKEY(OBS_KEY_AGRAVE)
OBS_HOTKEY(OBS_KEY_AACUTE)
OBS_HOTKEY(OBS_KEY_ACIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_ATILDE)
OBS_HOTKEY(OBS_KEY_ADIAERESIS)
OBS_HOTKEY(OBS_KEY_ARING)
OBS_HOTKEY(OBS_KEY_AE)
OBS_HOTKEY(OBS_KEY_CCEDILLA)
OBS_HOTKEY(OBS_KEY_EGRAVE)
OBS_HOTKEY(OBS_KEY_EACUTE)
OBS_HOTKEY(OBS_KEY_ECIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_EDIAERESIS)
OBS_HOTKEY(OBS_KEY_IGRAVE)
OBS_HOTKEY(OBS_KEY_IACUTE)
OBS_HOTKEY(OBS_KEY_ICIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_IDIAERESIS)
OBS_HOTKEY(OBS_KEY_ETH)
OBS_HOTKEY(OBS_KEY_NTILDE)
OBS_HOTKEY(OBS_KEY_OGRAVE)
OBS_HOTKEY(OBS_KEY_OACUTE)
OBS_HOTKEY(OBS_KEY_OCIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_OTILDE)
OBS_HOTKEY(OBS_KEY_ODIAERESIS)
OBS_HOTKEY(OBS_KEY_MULTIPLY)
OBS_HOTKEY(OBS_KEY_OOBLIQUE)
OBS_HOTKEY(OBS_KEY_UGRAVE)
OBS_HOTKEY(OBS_KEY_UACUTE)
OBS_HOTKEY(OBS_KEY_UCIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_UDIAERESIS)
OBS_HOTKEY(OBS_KEY_YACUTE)
OBS_HOTKEY(OBS_KEY_THORN)
OBS_HOTKEY(OBS_KEY_SSHARP)
OBS_HOTKEY(OBS_KEY_DIVISION)
OBS_HOTKEY(OBS_KEY_YDIAERESIS)
OBS_HOTKEY(OBS_KEY_MULTI_KEY)
OBS_HOTKEY(OBS_KEY_CODEINPUT)
OBS_HOTKEY(OBS_KEY_SINGLECANDIDATE)
OBS_HOTKEY(OBS_KEY_MULTIPLECANDIDATE)
OBS_HOTKEY(OBS_KEY_PREVIOUSCANDIDATE)
OBS_HOTKEY(OBS_KEY_MODE_SWITCH)
OBS_HOTKEY(OBS_KEY_KANJI)
OBS_HOTKEY(OBS_KEY_MUHENKAN)
OBS_HOTKEY(OBS_KEY_HENKAN)
OBS_HOTKEY(OBS_KEY_ROMAJI)
OBS_HOTKEY(OBS_KEY_HIRAGANA)
OBS_HOTKEY(OBS_KEY_KATAKANA)
OBS_HOTKEY(OBS_KEY_HIRAGANA_KATAKANA)
OBS_HOTKEY(OBS_KEY_ZENKAKU)
OBS_HOTKEY(OBS_KEY_HANKAKU)
OBS_HOTKEY(OBS_KEY_ZENKAKU_HANKAKU)
OBS_HOTKEY(OBS_KEY_TOUROKU)
OBS_HOTKEY(OBS_KEY_MASSYO)
OBS_HOTKEY(OBS_KEY_KANA_LOCK)
OBS_HOTKEY(OBS_KEY_KANA_SHIFT)
OBS_HOTKEY(OBS_KEY_EISU_SHIFT)
OBS_HOTKEY(OBS_KEY_EISU_TOGGLE)
OBS_HOTKEY(OBS_KEY_HANGUL)
OBS_HOTKEY(OBS_KEY_HANGUL_START)
OBS_HOTKEY(OBS_KEY_HANGUL_END)
OBS_HOTKEY(OBS_KEY_HANGUL_HANJA)
OBS_HOTKEY(OBS_KEY_HANGUL_JAMO)
OBS_HOTKEY(OBS_KEY_HANGUL_ROMAJA)
OBS_HOTKEY(OBS_KEY_HANGUL_JEONJA)
OBS_HOTKEY(OBS_KEY_HANGUL_BANJA)
OBS_HOTKEY(OBS_KEY_HANGUL_PREHANJA)
OBS_HOTKEY(OBS_KEY_HANGUL_POSTHANJA)
OBS_HOTKEY(OBS_KEY_HANGUL_SPECIAL)
OBS_HOTKEY(OBS_KEY_DEAD_GRAVE)
OBS_HOTKEY(OBS_KEY_DEAD_ACUTE)
OBS_HOTKEY(OBS_KEY_DEAD_CIRCUMFLEX)
OBS_HOTKEY(OBS_KEY_DEAD_TILDE)
OBS_HOTKEY(OBS_KEY_DEAD_MACRON)
OBS_HOTKEY(OBS_KEY_DEAD_BREVE)
OBS_HOTKEY(OBS_KEY_DEAD_ABOVEDOT)
OBS_HOTKEY(OBS_KEY_DEAD_DIAERESIS)
OBS_HOTKEY(OBS_KEY_DEAD_ABOVERING)
OBS_HOTKEY(OBS_KEY_DEAD_DOUBLEACUTE)
OBS_HOTKEY(OBS_KEY_DEAD_CARON)
OBS_HOTKEY(OBS_KEY_DEAD_CEDILLA)
OBS_HOTKEY(OBS_KEY_DEAD_OGONEK)
OBS_HOTKEY(OBS_KEY_DEAD_IOTA)
OBS_HOTKEY(OBS_KEY_DEAD_VOICED_SOUND)
OBS_HOTKEY(OBS_KEY_DEAD_SEMIVOICED_SOUND)
OBS_HOTKEY(OBS_KEY_DEAD_BELOWDOT)
OBS_HOTKEY(OBS_KEY_DEAD_HOOK)
OBS_HOTKEY(OBS_KEY_DEAD_HORN)
OBS_HOTKEY(OBS_KEY_BACK)
OBS_HOTKEY(OBS_KEY_FORWARD)
OBS_HOTKEY(OBS_KEY_STOP)
OBS_HOTKEY(OBS_KEY_REFRESH)
OBS_HOTKEY(OBS_KEY_VOLUMEDOWN)
OBS_HOTKEY(OBS_KEY_VOLUMEMUTE)
OBS_HOTKEY(OBS_KEY_VOLUMEUP)
OBS_HOTKEY(OBS_KEY_BASSBOOST)
OBS_HOTKEY(OBS_KEY_BASSUP)
OBS_HOTKEY(OBS_KEY_BASSDOWN)
OBS_HOTKEY(OBS_KEY_TREBLEUP)
OBS_HOTKEY(OBS_KEY_TREBLEDOWN)
OBS_HOTKEY(OBS_KEY_MEDIAPLAY)
OBS_HOTKEY(OBS_KEY_MEDIASTOP)
OBS_HOTKEY(OBS_KEY_MEDIAPREVIOUS)
OBS_HOTKEY(OBS_KEY_MEDIANEXT)
OBS_HOTKEY(OBS_KEY_MEDIARECORD)
OBS_HOTKEY(OBS_KEY_MEDIAPAUSE)
OBS_HOTKEY(OBS_KEY_MEDIATOGGLEPLAYPAUSE)
OBS_HOTKEY(OBS_KEY_HOMEPAGE)
OBS_HOTKEY(OBS_KEY_FAVORITES)
OBS_HOTKEY(OBS_KEY_SEARCH)
OBS_HOTKEY(OBS_KEY_STANDBY)
OBS_HOTKEY(OBS_KEY_OPENURL)
OBS_HOTKEY(OBS_KEY_LAUNCHMAIL)
OBS_HOTKEY(OBS_KEY_LAUNCHMEDIA)
OBS_HOTKEY(OBS_KEY_LAUNCH0)
OBS_HOTKEY(OBS_KEY_LAUNCH1)
OBS_HOTKEY(OBS_KEY_LAUNCH2)
OBS_HOTKEY(OBS_KEY_LAUNCH3)
OBS_HOTKEY(OBS_KEY_LAUNCH4)
OBS_HOTKEY(OBS_KEY_LAUNCH5)
OBS_HOTKEY(OBS_KEY_LAUNCH6)
OBS_HOTKEY(OBS_KEY_LAUNCH7)
OBS_HOTKEY(OBS_KEY_LAUNCH8)
OBS_HOTKEY(OBS_KEY_LAUNCH9)
OBS_HOTKEY(OBS_KEY_LAUNCHA)
OBS_HOTKEY(OBS_KEY_LAUNCHB)
OBS_HOTKEY(OBS_KEY_LAUNCHC)
OBS_HOTKEY(OBS_KEY_LAUNCHD)
OBS_HOTKEY(OBS_KEY_LAUNCHE)
OBS_HOTKEY(OBS_KEY_LAUNCHF)
OBS_HOTKEY(OBS_KEY_LAUNCHG)
OBS_HOTKEY(OBS_KEY_LAUNCHH)
OBS_HOTKEY(OBS_KEY_MONBRIGHTNESSUP)
OBS_HOTKEY(OBS_KEY_MONBRIGHTNESSDOWN)
OBS_HOTKEY(OBS_KEY_KEYBOARDLIGHTONOFF)
OBS_HOTKEY(OBS_KEY_KEYBOARDBRIGHTNESSUP)
OBS_HOTKEY(OBS_KEY_KEYBOARDBRIGHTNESSDOWN)
OBS_HOTKEY(OBS_KEY_POWEROFF)
OBS_HOTKEY(OBS_KEY_WAKEUP)
OBS_HOTKEY(OBS_KEY_EJECT)
OBS_HOTKEY(OBS_KEY_SCREENSAVER)
OBS_HOTKEY(OBS_KEY_WWW)
OBS_HOTKEY(OBS_KEY_MEMO)
OBS_HOTKEY(OBS_KEY_LIGHTBULB)
OBS_HOTKEY(OBS_KEY_SHOP)
OBS_HOTKEY(OBS_KEY_HISTORY)
OBS_HOTKEY(OBS_KEY_ADDFAVORITE)
OBS_HOTKEY(OBS_KEY_HOTLINKS)
OBS_HOTKEY(OBS_KEY_BRIGHTNESSADJUST)
OBS_HOTKEY(OBS_KEY_FINANCE)
OBS_HOTKEY(OBS_KEY_COMMUNITY)
OBS_HOTKEY(OBS_KEY_AUDIOREWIND)
OBS_HOTKEY(OBS_KEY_BACKFORWARD)
OBS_HOTKEY(OBS_KEY_APPLICATIONLEFT)
OBS_HOTKEY(OBS_KEY_APPLICATIONRIGHT)
OBS_HOTKEY(OBS_KEY_BOOK)
OBS_HOTKEY(OBS_KEY_CD)
OBS_HOTKEY(OBS_KEY_CALCULATOR)
OBS_HOTKEY(OBS_KEY_TODOLIST)
OBS_HOTKEY(OBS_KEY_CLEARGRAB)
OBS_HOTKEY(OBS_KEY_CLOSE)
OBS_HOTKEY(OBS_KEY_COPY)
OBS_HOTKEY(OBS_KEY_CUT)
OBS_HOTKEY(OBS_KEY_DISPLAY)
OBS_HOTKEY(OBS_KEY_DOS)
OBS_HOTKEY(OBS_KEY_DOCUMENTS)
OBS_HOTKEY(OBS_KEY_EXCEL)
OBS_HOTKEY(OBS_KEY_EXPLORER)
OBS_HOTKEY(OBS_KEY_GAME)
OBS_HOTKEY(OBS_KEY_GO)
OBS_HOTKEY(OBS_KEY_ITOUCH)
OBS_HOTKEY(OBS_KEY_LOGOFF)
OBS_HOTKEY(OBS_KEY_MARKET)
OBS_HOTKEY(OBS_KEY_MEETING)
OBS_HOTKEY(OBS_KEY_MENUKB)
OBS_HOTKEY(OBS_KEY_MENUPB)
OBS_HOTKEY(OBS_KEY_MYSITES)
OBS_HOTKEY(OBS_KEY_NEWS)
OBS_HOTKEY(OBS_KEY_OFFICEHOME)
OBS_HOTKEY(OBS_KEY_OPTION)
OBS_HOTKEY(OBS_KEY_PASTE)
OBS_HOTKEY(OBS_KEY_PHONE)
OBS_HOTKEY(OBS_KEY_CALENDAR)
OBS_HOTKEY(OBS_KEY_REPLY)
OBS_HOTKEY(OBS_KEY_RELOAD)
OBS_HOTKEY(OBS_KEY_ROTATEWINDOWS)
OBS_HOTKEY(OBS_KEY_ROTATIONPB)
OBS_HOTKEY(OBS_KEY_ROTATIONKB)
OBS_HOTKEY(OBS_KEY_SAVE)
OBS_HOTKEY(OBS_KEY_SEND)
OBS_HOTKEY(OBS_KEY_SPELL)
OBS_HOTKEY(OBS_KEY_SPLITSCREEN)
OBS_HOTKEY(OBS_KEY_SUPPORT)
OBS_HOTKEY(OBS_KEY_TASKPANE)
OBS_HOTKEY(OBS_KEY_TERMINAL)
OBS_HOTKEY(OBS_KEY_TOOLS)
OBS_HOTKEY(OBS_KEY_TRAVEL)
OBS_HOTKEY(OBS_KEY_VIDEO)
OBS_HOTKEY(OBS_KEY_WORD)
OBS_HOTKEY(OBS_KEY_XFER)
OBS_HOTKEY(OBS_KEY_ZOOMIN)
OBS_HOTKEY(OBS_KEY_ZOOMOUT)
OBS_HOTKEY(OBS_KEY_AWAY)
OBS_HOTKEY(OBS_KEY_MESSENGER)
OBS_HOTKEY(OBS_KEY_WEBCAM)
OBS_HOTKEY(OBS_KEY_MAILFORWARD)
OBS_HOTKEY(OBS_KEY_PICTURES)
OBS_HOTKEY(OBS_KEY_MUSIC)
OBS_HOTKEY(OBS_KEY_BATTERY)
OBS_HOTKEY(OBS_KEY_BLUETOOTH)
OBS_HOTKEY(OBS_KEY_WLAN)
OBS_HOTKEY(OBS_KEY_UWB)
OBS_HOTKEY(OBS_KEY_AUDIOFORWARD)
OBS_HOTKEY(OBS_KEY_AUDIOREPEAT)
OBS_HOTKEY(OBS_KEY_AUDIORANDOMPLAY)
OBS_HOTKEY(OBS_KEY_SUBTITLE)
OBS_HOTKEY(OBS_KEY_AUDIOCYCLETRACK)
OBS_HOTKEY(OBS_KEY_TIME)
OBS_HOTKEY(OBS_KEY_HIBERNATE)
OBS_HOTKEY(OBS_KEY_VIEW)
OBS_HOTKEY(OBS_KEY_TOPMENU)
OBS_HOTKEY(OBS_KEY_POWERDOWN)
OBS_HOTKEY(OBS_KEY_SUSPEND)
OBS_HOTKEY(OBS_KEY_CONTRASTADJUST)
OBS_HOTKEY(OBS_KEY_MEDIALAST)
OBS_HOTKEY(OBS_KEY_CALL)
OBS_HOTKEY(OBS_KEY_CAMERA)
OBS_HOTKEY(OBS_KEY_CAMERAFOCUS)
OBS_HOTKEY(OBS_KEY_CONTEXT1)
OBS_HOTKEY(OBS_KEY_CONTEXT2)
OBS_HOTKEY(OBS_KEY_CONTEXT3)
OBS_HOTKEY(OBS_KEY_CONTEXT4)
OBS_HOTKEY(OBS_KEY_FLIP)
OBS_HOTKEY(OBS_KEY_HANGUP)
OBS_HOTKEY(OBS_KEY_NO)
OBS_HOTKEY(OBS_KEY_SELECT)
OBS_HOTKEY(OBS_KEY_YES)
OBS_HOTKEY(OBS_KEY_TOGGLECALLHANGUP)
OBS_HOTKEY(OBS_KEY_VOICEDIAL)
OBS_HOTKEY(OBS_KEY_LASTNUMBERREDIAL)
OBS_HOTKEY(OBS_KEY_EXECUTE)
OBS_HOTKEY(OBS_KEY_PRINTER)
OBS_HOTKEY(OBS_KEY_PLAY)
OBS_HOTKEY(OBS_KEY_SLEEP)
OBS_HOTKEY(OBS_KEY_ZOOM)
OBS_HOTKEY(OBS_KEY_CANCEL)
#ifndef OBS_MOUSE_BUTTON
#define OBS_MOUSE_BUTTON(x) OBS_HOTKEY(x)
#define OBS_MOUSE_BUTTON_DEFAULT 1
#endif
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE1)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE2)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE3)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE4)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE5)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE6)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE7)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE8)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE9)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE10)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE11)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE12)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE13)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE14)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE15)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE16)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE17)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE18)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE19)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE20)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE21)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE22)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE23)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE24)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE25)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE26)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE27)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE28)
OBS_MOUSE_BUTTON(OBS_KEY_MOUSE29)
#ifdef OBS_MOUSE_BUTTON_DEFAULT
#undef OBS_MOUSE_BUTTON
#undef OBS_MOUSE_BUTTON_DEFAULT
#endif
......@@ -95,6 +95,65 @@ static inline bool check_path(const char *data, const char *path,
}
/* ------------------------------------------------------------------------- */
/* hotkeys */
struct obs_hotkey {
obs_hotkey_id id;
char *name;
char *description;
obs_hotkey_func func;
void *data;
int pressed;
obs_hotkey_registerer_t registerer_type;
void *registerer;
obs_hotkey_id pair_partner_id;
};
struct obs_hotkey_pair {
obs_hotkey_pair_id pair_id;
obs_hotkey_id id[2];
obs_hotkey_active_func func[2];
bool pressed0 : 1;
bool pressed1 : 1;
void *data[2];
};
typedef struct obs_hotkey_pair obs_hotkey_pair_t;
typedef struct obs_hotkeys_platform obs_hotkeys_platform_t;
void *obs_hotkey_thread(void *param);
struct obs_core_hotkeys;
bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys);
void obs_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys);
bool obs_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context,
obs_key_t key);
const char *obs_get_hotkey_translation(obs_key_t key, const char *def);
struct obs_context_data;
void obs_hotkeys_context_release(struct obs_context_data *context);
void obs_hotkeys_free(void);
struct obs_hotkey_binding {
obs_key_combination_t key;
bool pressed : 1;
bool modifiers_match : 1;
obs_hotkey_id hotkey_id;
obs_hotkey_t *hotkey;
};
struct obs_hotkey_name_map;
void obs_hotkey_name_map_free(void);
/* ------------------------------------------------------------------------- */
/* views */
......@@ -213,6 +272,41 @@ struct obs_core_data {
volatile bool valid;
};
/* user hotkeys */
struct obs_core_hotkeys {
pthread_mutex_t mutex;
DARRAY(obs_hotkey_t) hotkeys;
obs_hotkey_id next_id;
DARRAY(obs_hotkey_pair_t) hotkey_pairs;
obs_hotkey_pair_id next_pair_id;
pthread_t hotkey_thread;
bool hotkey_thread_initialized;
os_event_t *stop_event;
bool thread_disable_press : 1;
bool strict_modifiers : 1;
bool reroute_hotkeys : 1;
DARRAY(obs_hotkey_binding_t) bindings;
obs_hotkey_callback_router_func router_func;
void *router_func_data;
obs_hotkeys_platform_t *platform_context;
pthread_once_t name_map_init_token;
struct obs_hotkey_name_map *name_map;
signal_handler_t *signals;
char *translations[OBS_KEY_LAST_VALUE];
char *mute;
char *unmute;
char *push_to_mute;
char *push_to_talk;
char *sceneitem_show;
char *sceneitem_hide;
};
struct obs_core {
struct obs_module *first_module;
DARRAY(struct obs_module_path) module_paths;
......@@ -236,6 +330,7 @@ struct obs_core {
struct obs_core_video video;
struct obs_core_audio audio;
struct obs_core_data data;
struct obs_core_hotkeys hotkeys;
};
extern struct obs_core *obs;
......@@ -253,6 +348,10 @@ struct obs_context_data {
signal_handler_t *signals;
proc_handler_t *procs;
DARRAY(obs_hotkey_id) hotkeys;
DARRAY(obs_hotkey_pair_id) hotkey_pairs;
obs_data_t *hotkey_data;
DARRAY(char*) rename_cache;
pthread_mutex_t rename_cache_mutex;
......@@ -264,7 +363,8 @@ struct obs_context_data {
extern bool obs_context_data_init(
struct obs_context_data *context,
obs_data_t *settings,
const char *name);
const char *name,
obs_data_t *hotkey_data);
extern void obs_context_data_free(struct obs_context_data *context);
extern void obs_context_data_insert(struct obs_context_data *context,
......@@ -418,12 +518,26 @@ struct obs_source {
gs_texrender_t *filter_texrender;
enum obs_allow_direct_render allow_direct;
bool rendering_filter;
/* sources specific hotkeys */
obs_hotkey_pair_id mute_unmute_key;
obs_hotkey_id push_to_mute_key;
obs_hotkey_id push_to_talk_key;
bool push_to_mute_enabled : 1;
bool push_to_mute_pressed : 1;
bool push_to_talk_enabled : 1;
bool push_to_talk_pressed : 1;
uint64_t push_to_mute_delay;
uint64_t push_to_mute_stop_time;
uint64_t push_to_talk_delay;
uint64_t push_to_talk_stop_time;
};
extern const struct obs_source_info *find_source(struct darray *list,
const char *id);
extern bool obs_source_init_context(struct obs_source *source,
obs_data_t *settings, const char *name);
obs_data_t *settings, const char *name,
obs_data_t *hotkey_data);
extern bool obs_source_init(struct obs_source *source,
const struct obs_source_info *info);
......
此差异已折叠。
......@@ -47,9 +47,10 @@ static const char *output_signals[] = {
};
static bool init_output_handlers(struct obs_output *output, const char *name,
obs_data_t *settings)
obs_data_t *settings, obs_data_t *hotkey_data)
{
if (!obs_context_data_init(&output->context, settings, name))
if (!obs_context_data_init(&output->context, settings, name,
hotkey_data))
return false;
signal_handler_add_array(output->context.signals, output_signals);
......@@ -57,7 +58,7 @@ static bool init_output_handlers(struct obs_output *output, const char *name,
}
obs_output_t *obs_output_create(const char *id, const char *name,
obs_data_t *settings)
obs_data_t *settings, obs_data_t *hotkey_data)
{
const struct obs_output_info *info = find_output(id);
struct obs_output *output;
......@@ -73,7 +74,7 @@ obs_output_t *obs_output_create(const char *id, const char *name,
if (pthread_mutex_init(&output->interleaved_mutex, NULL) != 0)
goto fail;
if (!init_output_handlers(output, name, settings))
if (!init_output_handlers(output, name, settings, hotkey_data))
goto fail;
output->info = *info;
......
......@@ -473,7 +473,8 @@ const struct obs_source_info scene_info =
obs_scene_t *obs_scene_create(const char *name)
{
struct obs_source *source =
obs_source_create(OBS_SOURCE_TYPE_INPUT, "scene", name, NULL);
obs_source_create(OBS_SOURCE_TYPE_INPUT, "scene", name, NULL,
NULL);
return source->context.data;
}
......@@ -554,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;
......@@ -601,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(&params, "scene", scene);
calldata_set_ptr(&params, "item", item);
signal_handler_signal(scene->source->context.signals, "item_add",
......@@ -613,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);
......
......@@ -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;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -487,3 +487,7 @@ MuteCheckBox::indicator:checked {
MuteCheckBox::indicator:unchecked {
image: url(./Dark/unmute.png);
}
OBSHotkeyLabel[hotkeyPairHover=true] {
color: red;
}
此差异已折叠。
此差异已折叠。
......@@ -22,5 +22,6 @@
<file>images/settings/applications-system-2.png</file>
<file>images/settings/system-settings-3.png</file>
<file>images/settings/network-bluetooth.png</file>
<file>images/settings/preferences-desktop-keyboard-shortcuts.png</file>
</qresource>
</RCC>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册