wip xkbcommon

focus_loss
jackun 2 years ago
parent c68c48c02f
commit db9a23eb5a
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -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;

@ -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(&params, getenv("MANGOHUD_CONFIG"));
_params = &params;
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;
#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);
struct wsi_connection;
struct overlay_params;
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;
}
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
#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 = {&registry_add_object, &registry_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, &registry_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, &registry_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…
Cancel
Save