mirror of
https://github.com/flightlessmango/MangoHud.git
synced 2024-11-16 00:13:00 +00:00
wip xkbcommon
This commit is contained in:
parent
c68c48c02f
commit
db9a23eb5a
10
meson.build
10
meson.build
@ -84,6 +84,7 @@ vulkan_wsi_args = []
|
||||
vulkan_wsi_deps = []
|
||||
|
||||
if is_unixy
|
||||
dep_xkb = dependency('xkbcommon', required: true)
|
||||
dep_x11 = dependency('x11', required: get_option('with_x11'))
|
||||
dep_xcb = dependency('xcb', required: get_option('with_x11'))
|
||||
dep_wayland_client = dependency('wayland-client',
|
||||
@ -92,10 +93,15 @@ if is_unixy
|
||||
else
|
||||
dep_x11 = null_dep
|
||||
dep_xcb = null_dep
|
||||
dep_xkb = null_dep
|
||||
dep_wayland_client = null_dep
|
||||
dbus_dep = null_dep
|
||||
endif
|
||||
|
||||
if dep_xkb.found()
|
||||
pre_args += '-DHAVE_XKBCOMMON'
|
||||
endif
|
||||
|
||||
if dep_x11.found()
|
||||
vulkan_wsi_args += ['-DVK_USE_PLATFORM_XLIB_KHR']
|
||||
vulkan_wsi_deps += dep_x11.partial_dependency(compile_args : true, includes : true)
|
||||
@ -104,9 +110,9 @@ if dep_xcb.found()
|
||||
vulkan_wsi_args += ['-DVK_USE_PLATFORM_XCB_KHR']
|
||||
vulkan_wsi_deps += dep_xcb #.partial_dependency(compile_args : true, includes : true)
|
||||
endif
|
||||
if dep_wayland_client.found()
|
||||
if dep_wayland_client.found() and dep_xkb.found()
|
||||
vulkan_wsi_args += ['-DVK_USE_PLATFORM_WAYLAND_KHR']
|
||||
vulkan_wsi_deps += dep_wayland_client
|
||||
vulkan_wsi_deps += [dep_wayland_client, dep_xkb]
|
||||
endif
|
||||
|
||||
if is_unixy and not dep_x11.found() and not dep_wayland_client.found()
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "notify.h"
|
||||
#include "blacklist.h"
|
||||
#include "wsi_helpers.h"
|
||||
#include "keybinds.h"
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include "dbus_info.h"
|
||||
@ -115,7 +116,7 @@ void imgui_init()
|
||||
}
|
||||
|
||||
//static
|
||||
void imgui_create(void *ctx)
|
||||
void imgui_create(void *ctx, GL_SESSION gl_session)
|
||||
{
|
||||
if (inited)
|
||||
return;
|
||||
@ -172,6 +173,16 @@ void imgui_create(void *ctx)
|
||||
sw_stats.font_params_hash = params.font_params_hash;
|
||||
wsi_conn.focus_changed = focus_changed;
|
||||
|
||||
if (gl_session == GL_SESSION_X11)
|
||||
wsi_conn.keys_are_pressed = keys_are_pressed;
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
if (gl_session == GL_SESSION_WL)
|
||||
{
|
||||
wsi_conn.keys_are_pressed = wl_keys_are_pressed;
|
||||
wsi_wayland_init(wsi_conn);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Restore global context or ours might clash with apps that use Dear ImGui
|
||||
ImGui::SetCurrentContext(saved_ctx);
|
||||
}
|
||||
@ -191,7 +202,7 @@ void imgui_set_context(void *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
imgui_create(ctx);
|
||||
imgui_create(ctx, GL_SESSION_X11);
|
||||
}
|
||||
|
||||
void imgui_render(unsigned int width, unsigned int height)
|
||||
@ -205,7 +216,7 @@ void imgui_render(unsigned int width, unsigned int height)
|
||||
process_control_socket(control_client, params);
|
||||
}
|
||||
|
||||
check_keybinds(params, vendorID);
|
||||
check_keybinds(wsi_conn, params);
|
||||
update_hud_info(sw_stats, params, vendorID);
|
||||
|
||||
ImGuiContext *saved_ctx = ImGui::GetCurrentContext();
|
||||
|
@ -7,9 +7,18 @@
|
||||
|
||||
namespace MangoHud { namespace GL {
|
||||
|
||||
extern wsi_connection wsi_conn;
|
||||
|
||||
enum GL_SESSION
|
||||
{
|
||||
GL_SESSION_UNKNOWN,
|
||||
GL_SESSION_X11,
|
||||
GL_SESSION_WL,
|
||||
};
|
||||
|
||||
extern overlay_params params;
|
||||
void imgui_init();
|
||||
void imgui_create(void *ctx);
|
||||
void imgui_create(void *ctx, GL_SESSION);
|
||||
void imgui_shutdown();
|
||||
void imgui_set_context(void *ctx);
|
||||
void imgui_render(unsigned int width, unsigned int height);
|
||||
|
@ -10,10 +10,60 @@
|
||||
#include "mesa/util/os_time.h"
|
||||
#include "blacklist.h"
|
||||
#include "gl_hud.h"
|
||||
#include "wsi_helpers.h"
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#include <wayland-egl.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#define HAVE_MINCORE
|
||||
|
||||
using namespace MangoHud::GL;
|
||||
|
||||
EXPORT_C_(void *) eglGetProcAddress(const char* procName);
|
||||
namespace MangoHud { namespace GL {
|
||||
extern swapchain_stats sw_stats;
|
||||
extern wsi_connection wsi_conn;
|
||||
}}
|
||||
|
||||
EXPORT_C_(void*) eglGetProcAddress(const char* procName);
|
||||
static GL_SESSION egl_session = GL_SESSION_UNKNOWN;
|
||||
|
||||
// mesa eglglobals.c
|
||||
static bool pointer_is_dereferencable(void *p)
|
||||
{
|
||||
#ifdef HAVE_MINCORE
|
||||
uintptr_t addr = (uintptr_t) p;
|
||||
unsigned char valid = 0;
|
||||
const long page_size = getpagesize();
|
||||
|
||||
if (p == NULL)
|
||||
return false;
|
||||
|
||||
/* align addr to page_size */
|
||||
addr &= ~(page_size - 1);
|
||||
|
||||
if (mincore((void *) addr, page_size, &valid) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* mincore() returns 0 on success, and -1 on failure. The last parameter
|
||||
* is a vector of bytes with one entry for each page queried. mincore
|
||||
* returns page residency information in the first bit of each byte in the
|
||||
* vector.
|
||||
*
|
||||
* Residency doesn't actually matter when determining whether a pointer is
|
||||
* dereferenceable, so the output vector can be ignored. What matters is
|
||||
* whether mincore succeeds. See:
|
||||
*
|
||||
* http://man7.org/linux/man-pages/man2/mincore.2.html
|
||||
*/
|
||||
return true;
|
||||
#else
|
||||
return p != NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* get_egl_proc_address(const char* name) {
|
||||
|
||||
@ -48,6 +98,66 @@ EXPORT_C_(int) eglMakeCurrent_OFF(void *dpy, void *draw, void *read,void *ctx) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_C_(void*) eglGetDisplay(void* native_display)
|
||||
{
|
||||
static decltype(&eglGetDisplay) pfn_eglGetDisplay = nullptr;
|
||||
if (!pfn_eglGetDisplay)
|
||||
pfn_eglGetDisplay = reinterpret_cast<decltype(pfn_eglGetDisplay)>(get_egl_proc_address("eglGetDisplay"));
|
||||
|
||||
if (getenv("WAYLAND_DISPLAY"))
|
||||
{
|
||||
egl_session = GL_SESSION_WL;
|
||||
wsi_conn.wl.display = reinterpret_cast<wl_display*> (native_display);
|
||||
}
|
||||
else if (getenv("DISPLAY"))
|
||||
{
|
||||
egl_session = GL_SESSION_X11;
|
||||
wsi_conn.xlib.dpy = reinterpret_cast<Display*> (native_display);
|
||||
}
|
||||
|
||||
if (pointer_is_dereferencable(native_display))
|
||||
{
|
||||
Dl_info info;
|
||||
void *first_pointer = *(void **) native_display;
|
||||
dladdr(first_pointer, &info);
|
||||
if (info.dli_saddr)
|
||||
fprintf(stderr, "dli_sname: %s\n", info.dli_sname);
|
||||
}
|
||||
|
||||
return pfn_eglGetDisplay(native_display);
|
||||
}
|
||||
|
||||
EXPORT_C_(void*) eglCreateWindowSurface(void *egl_display, void *egl_config, void *native_window, int const * attrib_list)
|
||||
{
|
||||
static decltype(&eglCreateWindowSurface) pfn_eglCreateWindowSurface = nullptr;
|
||||
if (!pfn_eglCreateWindowSurface)
|
||||
pfn_eglCreateWindowSurface = reinterpret_cast<decltype(pfn_eglCreateWindowSurface)>(get_egl_proc_address("eglCreateWindowSurface"));
|
||||
|
||||
if (egl_session == GL_SESSION_WL)
|
||||
{
|
||||
// wsi_conn.wl.surface = reinterpret_cast<wl_surface*>(native_window);
|
||||
}
|
||||
else if (egl_session == GL_SESSION_X11)
|
||||
{
|
||||
wsi_conn.xlib.window = reinterpret_cast<Window>(native_window);
|
||||
}
|
||||
return pfn_eglCreateWindowSurface(egl_display, egl_config, native_window, attrib_list);
|
||||
}
|
||||
|
||||
EXPORT_C_(wl_egl_window*) wl_egl_window_create(wl_surface *surf, int w, int h)
|
||||
{
|
||||
static decltype(&wl_egl_window_create) pfn_wl_egl_window_create = nullptr;
|
||||
if (!pfn_wl_egl_window_create)
|
||||
{
|
||||
void *hlib = dlopen("libwayland-egl.so.1", RTLD_LAZY);
|
||||
pfn_wl_egl_window_create = reinterpret_cast<decltype(pfn_wl_egl_window_create)>(dlsym(hlib, "wl_egl_window_create"));
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", __func__);
|
||||
wsi_conn.wl.surface = surf;
|
||||
return pfn_wl_egl_window_create(surf, w, h);
|
||||
}
|
||||
|
||||
EXPORT_C_(unsigned int) eglSwapBuffers( void* dpy, void* surf)
|
||||
{
|
||||
static int (*pfn_eglSwapBuffers)(void*, void*) = nullptr;
|
||||
@ -59,7 +169,7 @@ EXPORT_C_(unsigned int) eglSwapBuffers( void* dpy, void* surf)
|
||||
if (!pfn_eglQuerySurface)
|
||||
pfn_eglQuerySurface = reinterpret_cast<decltype(pfn_eglQuerySurface)>(get_egl_proc_address("eglQuerySurface"));
|
||||
|
||||
imgui_create(surf);
|
||||
imgui_create(surf, egl_session);
|
||||
|
||||
int width=0, height=0;
|
||||
if (pfn_eglQuerySurface(dpy, surf, 0x3056, &height) &&
|
||||
@ -67,9 +177,9 @@ EXPORT_C_(unsigned int) eglSwapBuffers( void* dpy, void* surf)
|
||||
imgui_render(width, height);
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
if (fps_limit_stats.targetFrameTime > 0s){
|
||||
if (fps_limit_stats.targetFrameTime > 0s || (sw_stats.lost_focus && fps_limit_stats.focusLossFrameTime > 0s)){
|
||||
fps_limit_stats.frameStart = Clock::now();
|
||||
FpsLimiter(fps_limit_stats);
|
||||
FpsLimiter(fps_limit_stats, sw_stats.lost_focus);
|
||||
fps_limit_stats.frameEnd = Clock::now();
|
||||
}
|
||||
}
|
||||
@ -82,10 +192,12 @@ struct func_ptr {
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
static std::array<const func_ptr, 2> name_to_funcptr_map = {{
|
||||
static std::array<const func_ptr, 4> name_to_funcptr_map = {{
|
||||
#define ADD_HOOK(fn) { #fn, (void *) fn }
|
||||
ADD_HOOK(eglGetProcAddress),
|
||||
ADD_HOOK(eglSwapBuffers),
|
||||
ADD_HOOK(eglGetDisplay),
|
||||
ADD_HOOK(wl_egl_window_create),
|
||||
#undef ADD_HOOK
|
||||
}};
|
||||
|
||||
@ -102,7 +214,8 @@ EXPORT_C_(void *) mangohud_find_egl_ptr(const char *name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EXPORT_C_(void *) eglGetProcAddress(const char* procName) {
|
||||
void* eglGetProcAddress(const char* procName)
|
||||
{
|
||||
void* real_func = get_egl_proc_address(procName);
|
||||
void* func = mangohud_find_egl_ptr(procName);
|
||||
SPDLOG_TRACE("{}: proc: {}, real: {}, fun: {}", __func__, procName, real_func, func);
|
||||
|
@ -132,10 +132,10 @@ static void do_imgui_swap(void *dpy, void *drawable)
|
||||
{
|
||||
GLint vp[4];
|
||||
if (!is_blacklisted()) {
|
||||
imgui_create(glx.GetCurrentContext());
|
||||
|
||||
wsi_conn.xlib.dpy = (Display*)dpy;
|
||||
wsi_conn.xlib.window = (Window)drawable;
|
||||
imgui_create(glx.GetCurrentContext(), GL_SESSION_X11);
|
||||
|
||||
unsigned int width = -1, height = -1;
|
||||
|
||||
|
101
src/keybinds.cpp
101
src/keybinds.cpp
@ -1,10 +1,89 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <map>
|
||||
#include "overlay.h"
|
||||
#include "timing.hpp"
|
||||
#include "logging.h"
|
||||
#include "keybinds.h"
|
||||
#include <wayland-client.h>
|
||||
#include "wsi_helpers.h"
|
||||
|
||||
void check_keybinds(struct overlay_params& params, uint32_t vendorID){
|
||||
#ifdef HAVE_X11
|
||||
#include "shared_x11.h"
|
||||
#include "loaders/loader_x11.h"
|
||||
#endif
|
||||
|
||||
Clock::time_point last_f2_press, toggle_fps_limit_press , last_f12_press, reload_cfg_press, last_upload_press;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
std::map<xkb_keysym_t, bool> xkb_state;
|
||||
void wl_key_pressed(const xkb_keysym_t key, uint32_t state)
|
||||
{
|
||||
xkb_state[key] = !!state;
|
||||
}
|
||||
|
||||
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
|
||||
size_t pressed = 0;
|
||||
for (KeySym ks : keys) {
|
||||
if (xkb_state[ks])
|
||||
pressed++;
|
||||
}
|
||||
|
||||
if (pressed > 0 && pressed == keys.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_X11)
|
||||
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
|
||||
|
||||
if (!init_x11())
|
||||
return false;
|
||||
|
||||
char keys_return[32];
|
||||
size_t pressed = 0;
|
||||
|
||||
g_x11->XQueryKeymap(get_xdisplay(), keys_return);
|
||||
|
||||
for (KeySym ks : keys) {
|
||||
KeyCode kc2 = g_x11->XKeysymToKeycode(get_xdisplay(), ks);
|
||||
|
||||
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
|
||||
|
||||
if (isPressed)
|
||||
pressed++;
|
||||
}
|
||||
|
||||
if (pressed > 0 && pressed == keys.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
|
||||
size_t pressed = 0;
|
||||
|
||||
for (KeySym ks : keys) {
|
||||
if (GetAsyncKeyState(ks) & 0x8000)
|
||||
pressed++;
|
||||
}
|
||||
|
||||
if (pressed > 0 && pressed == keys.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void check_keybinds(wsi_connection& wsi, struct overlay_params& params){
|
||||
using namespace std::chrono_literals;
|
||||
auto now = Clock::now(); /* us */
|
||||
auto elapsedF2 = now - last_f2_press;
|
||||
@ -20,8 +99,14 @@ void check_keybinds(struct overlay_params& params, uint32_t vendorID){
|
||||
|
||||
auto keyPressDelay = 400ms;
|
||||
|
||||
if (!wsi.keys_are_pressed)
|
||||
{
|
||||
SPDLOG_DEBUG("wsi.keys_are_pressed is not set!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (elapsedF2 >= keyPressDelay &&
|
||||
keys_are_pressed(params.toggle_logging)) {
|
||||
wsi.keys_are_pressed(params.toggle_logging)) {
|
||||
last_f2_press = now;
|
||||
if (logger->is_active()) {
|
||||
logger->stop_logging();
|
||||
@ -32,7 +117,7 @@ void check_keybinds(struct overlay_params& params, uint32_t vendorID){
|
||||
}
|
||||
|
||||
if (elapsedFpsLimitToggle >= keyPressDelay &&
|
||||
keys_are_pressed(params.toggle_fps_limit)) {
|
||||
wsi.keys_are_pressed(params.toggle_fps_limit)) {
|
||||
toggle_fps_limit_press = now;
|
||||
for (size_t i = 0; i < params.fps_limit.size(); i++){
|
||||
uint32_t fps_limit = params.fps_limit[i];
|
||||
@ -51,26 +136,26 @@ void check_keybinds(struct overlay_params& params, uint32_t vendorID){
|
||||
}
|
||||
|
||||
if (elapsedF12 >= keyPressDelay &&
|
||||
keys_are_pressed(params.toggle_hud)) {
|
||||
wsi.keys_are_pressed(params.toggle_hud)) {
|
||||
last_f12_press = now;
|
||||
params.no_display = !params.no_display;
|
||||
}
|
||||
|
||||
if (elapsedReloadCfg >= keyPressDelay &&
|
||||
keys_are_pressed(params.reload_cfg)) {
|
||||
wsi.keys_are_pressed(params.reload_cfg)) {
|
||||
parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"));
|
||||
_params = ¶ms;
|
||||
reload_cfg_press = now;
|
||||
}
|
||||
|
||||
if (params.permit_upload && elapsedUpload >= keyPressDelay &&
|
||||
keys_are_pressed(params.upload_log)) {
|
||||
wsi.keys_are_pressed(params.upload_log)) {
|
||||
last_upload_press = now;
|
||||
logger->upload_last_log();
|
||||
}
|
||||
|
||||
if (params.permit_upload && elapsedUpload >= keyPressDelay &&
|
||||
keys_are_pressed(params.upload_logs)) {
|
||||
wsi.keys_are_pressed(params.upload_logs)) {
|
||||
last_upload_press = now;
|
||||
logger->upload_last_logs();
|
||||
}
|
||||
|
@ -1,64 +1,21 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_KEYBINDS_H
|
||||
#define MANGOHUD_KEYBINDS_H
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_X11
|
||||
#include "shared_x11.h"
|
||||
#include "loaders/loader_x11.h"
|
||||
#ifdef HAVE_XKBCOMMON
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#else
|
||||
typedef uint32_t xkb_keysym_t;
|
||||
#endif
|
||||
|
||||
#ifndef KeySym
|
||||
typedef unsigned long KeySym;
|
||||
struct wsi_connection;
|
||||
struct overlay_params;
|
||||
|
||||
void check_keybinds(wsi_connection&, overlay_params& params);
|
||||
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys);
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys);
|
||||
void wl_key_pressed(const xkb_keysym_t key, uint32_t state);
|
||||
#endif
|
||||
|
||||
Clock::time_point last_f2_press, toggle_fps_limit_press , last_f12_press, reload_cfg_press, last_upload_press;
|
||||
|
||||
#if defined(HAVE_X11)
|
||||
bool keys_are_pressed(const std::vector<KeySym>& keys) {
|
||||
|
||||
if (!init_x11())
|
||||
return false;
|
||||
|
||||
char keys_return[32];
|
||||
size_t pressed = 0;
|
||||
|
||||
g_x11->XQueryKeymap(get_xdisplay(), keys_return);
|
||||
|
||||
for (KeySym ks : keys) {
|
||||
KeyCode kc2 = g_x11->XKeysymToKeycode(get_xdisplay(), ks);
|
||||
|
||||
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
|
||||
|
||||
if (isPressed)
|
||||
pressed++;
|
||||
}
|
||||
|
||||
if (pressed > 0 && pressed == keys.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
bool keys_are_pressed(const std::vector<KeySym>& keys) {
|
||||
size_t pressed = 0;
|
||||
|
||||
for (KeySym ks : keys) {
|
||||
if (GetAsyncKeyState(ks) & 0x8000)
|
||||
pressed++;
|
||||
}
|
||||
|
||||
if (pressed > 0 && pressed == keys.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#else // XXX: Add wayland support
|
||||
bool keys_are_pressed(const std::vector<KeySym>& keys) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //MANGOHUD_KEYBINDS_H
|
||||
|
@ -108,7 +108,6 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const stru
|
||||
void update_hw_info(const struct overlay_params& params, uint32_t vendorID);
|
||||
void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_params& params);
|
||||
void init_cpu_stats(overlay_params& params);
|
||||
void check_keybinds(overlay_params& params, uint32_t vendorID);
|
||||
void init_system_info(void);
|
||||
void FpsLimiter(struct fps_limit& stats, bool lost_focus = false);
|
||||
std::string get_device_name(uint32_t vendorID, uint32_t deviceID);
|
||||
|
@ -124,22 +124,19 @@ parse_float(const char *str)
|
||||
return val;
|
||||
}
|
||||
|
||||
#ifdef HAVE_X11
|
||||
static std::vector<KeySym>
|
||||
#ifdef HAVE_XKBCOMMON
|
||||
static std::vector<xkb_keysym_t>
|
||||
parse_string_to_keysym_vec(const char *str)
|
||||
{
|
||||
std::vector<KeySym> keys;
|
||||
if(g_x11->IsLoaded())
|
||||
{
|
||||
auto keyStrings = str_tokenize(str);
|
||||
for (auto& ks : keyStrings) {
|
||||
trim(ks);
|
||||
KeySym xk = g_x11->XStringToKeysym(ks.c_str());
|
||||
if (xk)
|
||||
keys.push_back(xk);
|
||||
else
|
||||
SPDLOG_ERROR("Unrecognized key: '{}'", ks);
|
||||
}
|
||||
std::vector<xkb_keysym_t> keys;
|
||||
auto keyStrings = str_tokenize(str);
|
||||
for (auto& ks : keyStrings) {
|
||||
trim(ks);
|
||||
auto xk = xkb_keysym_from_name(ks.c_str(), XKB_KEYSYM_NO_FLAGS);
|
||||
if (xk)
|
||||
keys.push_back(xk);
|
||||
else
|
||||
SPDLOG_ERROR("Unrecognized key: '{}'", ks);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -235,12 +236,12 @@ struct overlay_params {
|
||||
float font_scale_media_player;
|
||||
float background_alpha, alpha;
|
||||
float cellpadding_y;
|
||||
std::vector<KeySym> toggle_hud;
|
||||
std::vector<KeySym> toggle_fps_limit;
|
||||
std::vector<KeySym> toggle_logging;
|
||||
std::vector<KeySym> reload_cfg;
|
||||
std::vector<KeySym> upload_log;
|
||||
std::vector<KeySym> upload_logs;
|
||||
std::vector<xkb_keysym_t> toggle_hud;
|
||||
std::vector<xkb_keysym_t> toggle_fps_limit;
|
||||
std::vector<xkb_keysym_t> toggle_logging;
|
||||
std::vector<xkb_keysym_t> reload_cfg;
|
||||
std::vector<xkb_keysym_t> upload_log;
|
||||
std::vector<xkb_keysym_t> upload_logs;
|
||||
std::string time_format, output_folder, output_file;
|
||||
std::string pci_dev;
|
||||
std::string media_player_name;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "blacklist.h"
|
||||
#include "pci_ids.h"
|
||||
#include "wsi_helpers.h"
|
||||
#include "keybinds.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -430,6 +431,7 @@ static VkResult overlay_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurf
|
||||
struct surface_data *data = new_surface_data(*pSurface);
|
||||
data->wsi.xcb.conn = pCreateInfo->connection;
|
||||
data->wsi.xcb.window = pCreateInfo->window;
|
||||
data->wsi.keys_are_pressed = keys_are_pressed;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -447,13 +449,14 @@ static VkResult overlay_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSu
|
||||
struct surface_data *data = new_surface_data(*pSurface);
|
||||
data->wsi.xlib.dpy = pCreateInfo->dpy;
|
||||
data->wsi.xlib.window = pCreateInfo->window;
|
||||
data->wsi.keys_are_pressed = keys_are_pressed;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
extern void wayland_init(wsi_connection&);
|
||||
extern void wsi_wayland_init(wsi_connection&);
|
||||
static VkResult overlay_CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
|
||||
{
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
@ -464,7 +467,9 @@ static VkResult overlay_CreateWaylandSurfaceKHR(VkInstance instance, const VkWay
|
||||
struct surface_data *data = new_surface_data(*pSurface);
|
||||
data->wsi.wl.display = pCreateInfo->display;
|
||||
data->wsi.wl.surface = pCreateInfo->surface;
|
||||
wayland_init(data->wsi);
|
||||
data->wsi.keys_are_pressed = wl_keys_are_pressed;
|
||||
data->wsi.key_pressed = wl_key_pressed;
|
||||
wsi_wayland_init(data->wsi);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -531,7 +536,7 @@ static void snapshot_swapchain_frame(struct swapchain_data *data)
|
||||
struct device_data *device_data = data->device;
|
||||
struct instance_data *instance_data = device_data->instance;
|
||||
update_hud_info(data->sw_stats, instance_data->params, device_data->properties.vendorID);
|
||||
check_keybinds(instance_data->params, device_data->properties.vendorID);
|
||||
check_keybinds(data->surface_data->wsi, instance_data->params);
|
||||
#ifdef __linux__
|
||||
if (instance_data->params.control >= 0) {
|
||||
control_client_check(instance_data->params.control, instance_data->control_client, gpu.c_str());
|
||||
|
@ -1,5 +1,11 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#endif
|
||||
#include "wsi_helpers.h"
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
@ -9,10 +15,10 @@ static bool check_window_focus(xcb_connection_t * connection, xcb_window_t windo
|
||||
auto reply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
|
||||
if (reply)
|
||||
{
|
||||
SPDLOG_DEBUG("Window: {:08x} Focus WId: {:08x}", window, reply->focus);
|
||||
bool has_focus = (window == reply->focus);
|
||||
free(reply);
|
||||
return has_focus;
|
||||
SPDLOG_DEBUG("Window: {:08x} Focus WId: {:08x}", window, reply->focus);
|
||||
bool has_focus = (window == reply->focus);
|
||||
free(reply);
|
||||
return has_focus;
|
||||
}
|
||||
|
||||
// xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, reply->focus);
|
||||
@ -92,33 +98,56 @@ void window_has_focus(wsi_connection* conn)
|
||||
#endif
|
||||
}
|
||||
|
||||
struct interfaces_
|
||||
struct wl_state
|
||||
{
|
||||
wl_shell *shell;
|
||||
wl_seat *seat;
|
||||
// wl_shell *shell;
|
||||
// wl_seat *seat;
|
||||
wsi_connection *wsi;
|
||||
};
|
||||
xkb_context *ctx;
|
||||
xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
} g_wl_state {}; //TODO per surface etc instance?
|
||||
|
||||
static void keyboard_keymap (void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) {
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
|
||||
assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);
|
||||
char *map_shm = reinterpret_cast<char *>(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
assert(map_shm != MAP_FAILED);
|
||||
|
||||
xkb_keymap_unref(g_wl_state.keymap);
|
||||
g_wl_state.keymap = xkb_keymap_new_from_string(g_wl_state.ctx, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS); // FIXME probably leaking stuff
|
||||
munmap(map_shm, size);
|
||||
close(fd);
|
||||
|
||||
xkb_state_unref(g_wl_state.state);
|
||||
g_wl_state.state = xkb_state_new(g_wl_state.keymap); // FIXME probably leaking stuff
|
||||
}
|
||||
|
||||
static void keyboard_enter (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
auto wsi = reinterpret_cast<wsi_connection*>(data);
|
||||
SPDLOG_DEBUG("{}: {} == {}", __func__, (void*)wsi->wl.surface, (void*)surface);
|
||||
if (wsi->focus_changed && surface == wsi->wl.surface)
|
||||
wsi->focus_changed(true);
|
||||
}
|
||||
|
||||
static void keyboard_leave (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
SPDLOG_DEBUG("{}: {}", __func__, (void*)surface);
|
||||
auto wsi = reinterpret_cast<wsi_connection*>(data);
|
||||
if (wsi->focus_changed && surface == wsi->wl.surface)
|
||||
wsi->focus_changed(false);
|
||||
}
|
||||
|
||||
static void keyboard_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||
SPDLOG_DEBUG("{}: key pressed: {}", __func__, key);
|
||||
auto wsi = reinterpret_cast<wsi_connection*>(data);
|
||||
uint32_t keycode = key + 8;
|
||||
|
||||
xkb_keysym_t sym = xkb_state_key_get_one_sym(g_wl_state.state, keycode);
|
||||
if (wsi->key_pressed)
|
||||
wsi->key_pressed(sym, state);
|
||||
|
||||
SPDLOG_DEBUG("{}: key pressed: {}, {}, {:08x}", __func__, key, state, sym);
|
||||
}
|
||||
|
||||
static void keyboard_modifiers (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
|
||||
@ -130,7 +159,7 @@ static struct wl_keyboard_listener keyboard_listener = {&keyboard_keymap, &keybo
|
||||
static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabilities) {
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
|
||||
SPDLOG_DEBUG("SEAT");
|
||||
SPDLOG_DEBUG("Got usable seat");
|
||||
struct wl_keyboard *keyboard = wl_seat_get_keyboard (seat);
|
||||
wl_keyboard_add_listener (keyboard, &keyboard_listener, data);
|
||||
}
|
||||
@ -139,7 +168,7 @@ static struct wl_seat_listener seat_listener = {&seat_capabilities};
|
||||
|
||||
static void registry_add_object (void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
|
||||
SPDLOG_DEBUG("{}", __func__);
|
||||
if (!strcmp(interface,"wl_seat")) {
|
||||
if (!strcmp(interface, "wl_seat")) {
|
||||
//input_reader* ir = wl_registry_get_user_data(registry);
|
||||
auto seat = (wl_seat*)wl_registry_bind (registry, name, &wl_seat_interface, 1);
|
||||
// SPDLOG_DEBUG("wl_seat_add_listener {}", wl_proxy_get_listener((wl_proxy*)seat));
|
||||
@ -152,11 +181,11 @@ static void registry_remove_object (void *data, struct wl_registry *registry, ui
|
||||
|
||||
static struct wl_registry_listener registry_listener = {®istry_add_object, ®istry_remove_object};
|
||||
|
||||
// interfaces_ g_interfaces {};
|
||||
|
||||
void wayland_init(wsi_connection& conn)
|
||||
void wsi_wayland_init(wsi_connection& conn)
|
||||
{
|
||||
auto registry = wl_display_get_registry(conn.wl.display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, &conn);
|
||||
wl_display_roundtrip(conn.wl.display);
|
||||
auto registry = wl_display_get_registry(conn.wl.display);
|
||||
g_wl_state.ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); //FIXME probably leaking stuff
|
||||
g_wl_state.wsi = &conn; //TODO per surfacei nstance?
|
||||
wl_registry_add_listener(registry, ®istry_listener, &conn);
|
||||
wl_display_roundtrip(conn.wl.display);
|
||||
}
|
||||
|
@ -1,5 +1,13 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_XKBCOMMON
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#else
|
||||
typedef uint32_t xkb_keysym_t;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#include "loaders/loader_x11.h"
|
||||
#endif
|
||||
@ -16,28 +24,32 @@
|
||||
struct wsi_connection
|
||||
{
|
||||
std::function<void(bool)> focus_changed;
|
||||
std::function<void(xkb_keysym_t, uint32_t)> key_pressed;
|
||||
std::function<bool(const std::vector<xkb_keysym_t>& keys)> keys_are_pressed;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
struct xcb {
|
||||
xcb_connection_t *conn = nullptr;
|
||||
xcb_window_t window = 0;
|
||||
xcb_connection_t *conn;
|
||||
xcb_window_t window;
|
||||
} xcb;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
struct xlib {
|
||||
Display *dpy = nullptr;
|
||||
Window window = 0;
|
||||
int evmask = 0;
|
||||
Display *dpy;
|
||||
Window window;
|
||||
int evmask;
|
||||
} xlib;
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
struct wl {
|
||||
wl_display *display;
|
||||
wl_surface *surface;
|
||||
bool has_focus;
|
||||
} wl;
|
||||
#endif
|
||||
};
|
||||
|
||||
// struct wsi_connection;
|
||||
// bool check_window_focus(const wsi_connection&);
|
||||
|
||||
void wsi_wayland_init(wsi_connection& conn);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user