Xkb:如何将键码转换为键符号

2023-11-23

我只是尝试获取 KeyCode 和修饰符掩码,并使用 Xkb 扩展将其转换为 KeySym。我似乎无法弄清楚为什么这不起作用。很明显修饰符不匹配,但我不知道为什么。我什至不知道我是否正确转换了该组。

#include <stdio.h>
#include <stdlib.h>
#include <X11/X.h>
#include <X11/XKBlib.h>

void check(XkbDescPtr keyboard_map, KeyCode keycode, unsigned int mask) {
    //What the hell is diff between XkbKeyGroupInfo and XkbKeyNumGroups?
    unsigned char info = XkbKeyGroupInfo(keyboard_map, keycode);
    int num_groups = XkbKeyNumGroups(keyboard_map, keycode);

    int key_width = XkbKeyGroupsWidth(keyboard_map, keycode);
    //int num_syms = XkbKeyNumSyms(keyboard_map, keycode);

    //Get the group
    unsigned int group = 0; // What should this default to?
    switch (XkbOutOfRangeGroupAction(info)) {
        case XkbRedirectIntoRange:
            /* If the RedirectIntoRange flag is set, the four least significant 
            * bits of the groups wrap control specify the index of a group to 
            * which all illegal groups correspond. If the specified group is 
            * also out of range, all illegal groups map to Group1.
            */
            printf("XkbRedirectIntoRange\n");
            group = XkbOutOfRangeGroupInfo(info);
            if (group >= num_groups) {
                group = 0;
            }
        break;

        case XkbClampIntoRange:
            /* If the ClampIntoRange flag is set, out-of-range groups correspond 
            * to the nearest legal group. Effective groups larger than the 
            * highest supported group are mapped to the highest supported group; 
            * effective groups less than Group1 are mapped to Group1 . For 
            * example, a key with two groups of symbols uses Group2 type and 
            * symbols if the global effective group is either Group3 or Group4.
            */
            printf("XkbClampIntoRange\n");
            group = num_groups - 1;
        break;

        case XkbWrapIntoRange:
            /* If neither flag is set, group is wrapped into range using integer 
            * modulus. For example, a key with two groups of symbols for which 
            * groups wrap uses Group1 symbols if the global effective group is 
            * Group3 or Group2 symbols if the global effective group is Group4.
            */
            printf("XkbWrapIntoRange\n");
        default:
            printf("Default\n");
            if (num_groups != 0) {
                group %= num_groups;
            }
        break;
    }
    printf("Group Info %d, %d, %d\n", group, num_groups, key_width);
    //printf("Mask Info %d, %d, %d, %d, %d, %d, %d, %d\n", ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask);

    XkbKeyTypePtr key_type = XkbKeyKeyType(keyboard_map, keycode, group);

    KeySym keysym = NoSymbol;
    int i;
    for (i = 0; i < key_type->map_count; i++) {
        if (key_type->map[i].active &&  key_type->map[i].mods.mask == mask) {
            keysym = XkbKeySymEntry(keyboard_map, keycode, i, group);
        }
    }

    //printf("%s\n", XKeysymToString(keysym));
    printf("KeyCode: %d\n", (int) keycode);
    printf("KeySym:  %d\n", (int) keysym);
}

int main(int argc, const char * argv[]) {
    Display * display;

    //Try to attach to the default X11 display.
    display = XOpenDisplay(NULL);
    if(display == NULL) {
        printf("Error: Could not open display!\n");
        return EXIT_FAILURE;
    }

    //Get the map
    XkbDescPtr keyboard_map = XkbGetMap(display, XkbAllClientInfoMask, XkbUseCoreKbd);

    KeyCode keycode = 56; // b
    check(keyboard_map, keycode, ShiftMask | LockMask | ControlMask);

    //Close the connection to the selected X11 display.
    XCloseDisplay(display);

    return EXIT_SUCCESS;
}

经过多次尝试和错误后,我终于弄清楚了。 XKeycodeToKeysym 显然已损坏,并且未为扩展索引定义索引值计算。

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/X.h>
#include <X11/XKBlib.h>

KeySym KeyCodeToKeySym(Display * display, KeyCode keycode, unsigned int event_mask) {
    KeySym keysym = NoSymbol;

    //Get the map
    XkbDescPtr keyboard_map = XkbGetMap(display, XkbAllClientInfoMask, XkbUseCoreKbd);
    if (keyboard_map) {
        //What is diff between XkbKeyGroupInfo and XkbKeyNumGroups?
        unsigned char info = XkbKeyGroupInfo(keyboard_map, keycode);
        unsigned int num_groups = XkbKeyNumGroups(keyboard_map, keycode);

        //Get the group
        unsigned int group = 0x00;
        switch (XkbOutOfRangeGroupAction(info)) {
            case XkbRedirectIntoRange:
                /* If the RedirectIntoRange flag is set, the four least significant
                 * bits of the groups wrap control specify the index of a group to
                 * which all illegal groups correspond. If the specified group is
                 * also out of range, all illegal groups map to Group1.
                 */
                group = XkbOutOfRangeGroupInfo(info);
                if (group >= num_groups) {
                    group = 0;
                }
            break;

            case XkbClampIntoRange:
                /* If the ClampIntoRange flag is set, out-of-range groups correspond
                 * to the nearest legal group. Effective groups larger than the
                 * highest supported group are mapped to the highest supported group;
                 * effective groups less than Group1 are mapped to Group1 . For
                 * example, a key with two groups of symbols uses Group2 type and
                 * symbols if the global effective group is either Group3 or Group4.
                 */
                group = num_groups - 1;
            break;

            case XkbWrapIntoRange:
                /* If neither flag is set, group is wrapped into range using integer
                 * modulus. For example, a key with two groups of symbols for which
                 * groups wrap uses Group1 symbols if the global effective group is
                 * Group3 or Group2 symbols if the global effective group is Group4.
                 */
            default:
                if (num_groups != 0) {
                    group %= num_groups;
                }
            break;
        }

        XkbKeyTypePtr key_type = XkbKeyKeyType(keyboard_map, keycode, group);
        unsigned int active_mods = event_mask & key_type->mods.mask;

        int i, level = 0;
        for (i = 0; i < key_type->map_count; i++) {
            if (key_type->map[i].active && key_type->map[i].mods.mask == active_mods) {
                level = key_type->map[i].level;
            }
        }

        keysym = XkbKeySymEntry(keyboard_map, keycode, level, group);
        XkbFreeClientMap(keyboard_map, XkbAllClientInfoMask, true);
    }

    return keysym;
}

int main(int argc, const char * argv[]) {
    Display * display;

    //Try to attach to the default X11 display.
    display = XOpenDisplay(NULL);
    if(display == NULL) {
        printf("Error: Could not open display!\n");
        return EXIT_FAILURE;
    }

    KeyCode keycode = 56; // b
    unsigned int event_mask = ShiftMask | LockMask;
    KeySym keysym = KeyCodeToKeySym(display, keycode, event_mask);

    printf("KeySym: %s\n", XKeysymToString(keysym));

    //Close the connection to the selected X11 display.
    XCloseDisplay(display);

    return EXIT_SUCCESS;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Xkb:如何将键码转换为键符号 的相关文章

  • 如何在 Linux 主机上的 docker 容器中挂载目录 [重复]

    这个问题在这里已经有答案了 我想将一个目录从 docker 容器挂载到本地文件系统 该目录是网站根目录 我需要能够使用任何编辑器在本地计算机上编辑它 我知道我可以跑docker run v local path container path
  • Yocto“无法运行 qemu:无法初始化 SDL(x11 不 > 可用)”

    所以我在本地构建服务器上安装了 Yocto 因为谁希望大规模构建占用他们的工作区 amirite 主机和服务器是Arch Linux 4 19 44 1 lts 无论如何 我只是从找到的快速构建页面运行示例here https www yo
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • 如何从 Linux 命令行获取视频文件的分辨率(宽度和高度)?

    我一直在挖掘 mplayer mencoder 和 ffmpeg 文档 但我似乎无法想出anything 我对输出格式不是特别挑剔 因为我可以使用正则表达式将其拉出来 我只是似乎无法首先获取数据 Use ffprobe https ffmp
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • jQuery 键盘事件处理程序按住

    我想为游戏创建一个简单的事件处理程序 这是我的代码 document keydown function e switch e keyCode case 65 left a console log left break case 68 rig
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 无需 cron 在后台发送邮件

    我想知道是否有一种方法可以运行 PHP 循环 以便在后台向订阅者发送几百封电子邮件 我的目标是格式化新闻通讯 单击发送 然后关闭浏览器或更改页面 当然 发送电子邮件的实际过程将在后台运行 不会因浏览器关闭而中断 我知道这可以通过 cron
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • Composer 安装要求

    我正在尝试将 Composer 安装到 Laravel 项目中 当我做的时候sudo composer install在项目目录中它显示了两个错误 Problem 1 Installation request for simplesoftw
  • Linux 桌面快捷方式和安装图标

    我需要添加什么到我的 spec文件来创建桌面快捷方式并在安装过程中为快捷方式分配一个图标 rpm 如果需要脚本 一个示例将非常有帮助 您在 Linux 下使用 desktop 文件作为图标 图标放置的位置取决于您使用的发行版和桌面环境 由于
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • 如何制作和应用SVN补丁?

    我想制作一个SVN类型的补丁文件httpd conf这样我就可以轻松地将其应用到其他主机上 If I do cd root diff Naur etc httpd conf httpd conf original etc httpd con
  • 嵌入式Linux poll()不断返回

    我有一个特别的问题 当我知道没有什么可读时 民意调查不断返回 因此设置如下 我有 2 个文件描述符 它们构成fd设置民意调查监视 一种用于引脚从高到低的变化 GPIO 另一个用于代理输入 代理输入出现问题 处理的顺序是 启动main函数 然

随机推荐

  • 如何精确测量绳子的宽度?

    首先 问一个问题How to measure width of character precisely 这是回答 对于这种情况并没有真正的帮助 所以这不是那个的重复 我有一根绳子 我画画使用graphics DrawString 但是当我需
  • 三角形网格的测地线计算? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我试图找到三角表面上两点之间的距离 测地距离 这看起来像是一个基本操作 但并不简单 所以我想知道是否有任何图书馆可以做到这一点 我的谷歌搜索失败了
  • 从 Android-NDK 应用程序发送意图

    我正在 android 下用 C 编写一个本机应用程序 我需要广播一些意图 这可能吗 如果您要向我指出 JNI 请给我更多详细信息 因为我不确定这是如何完成的 如果这是不可能的 我会做的是在 NDK 守护进程和 Java Android S
  • 何时在 UIComponent 上调用 setValue 和 setSubscribedValue?

    如果我正确地组合了 BalusC 2006 年精彩帖子中包含的信息http balusc blogspot ch 2006 09 debug jsf lifecycle html擎天柱的更早的帖子http cagataycivici wor
  • JavaScript 中的两种方式哈希 JSON 字符串以在 URL 中使用

    我想获取一个 JSON 字符串并对其进行加密 哈希 编码 以便我可以将其放入 URL 中 使其类似于如下所示 var stringToEncode JSON stringify foo baz bar 1 2 3 4 5 baz fizzl
  • 在 WinForms 应用程序中嵌入视频

    我需要能够使用 C 在 WinForms 应用程序中嵌入并控制 AVI 文件的播放 视频需要嵌入到表单中 而不是在单独的媒体播放器窗口中启动 执行此操作的最佳方法是什么 我发现了 System Media 命名空间 这听起来很有希望 但似乎
  • 无法在 R Markdown 中使用 Rcpp 引擎

    我尝试过了Knit HTML以下 Rmd 文件 title Untitled author Florian Priv date 12 septembre 2016 output html document r fibCpp engine R
  • 在内存而不是文件系统中创建文件

    我正在使用 NET 库函数将文件上传到服务器 并将文件路径作为参数 我想要发送的数据很小并且是在运行时构建的 我可以将其保存到临时文件 然后上传 由于我的应用程序将部署在各种环境中 并且我不知道是否能够可靠地创建临时文件 因此最好能够传递到
  • 如何分发Java应用程序

    我想了解分发 Java 应用程序的各种选项 我知道你可以 分发源代码并让用户自己编译 或提供make文件等 将其打包成 JAR 并具有自解压档案 和 我确信 还有无数其他方式 我希望对最常见的选项 以及我没有想到的选项 进行一些解释 特别是
  • Chrome 扩展 + Devise + Rails 应用程序 - 从扩展发出经过身份验证的请求?

    我正在构建一个 Chrome 扩展程序 可以直接从浏览器创建联系人 而无需转到我的由 devise 驱动的 Rails 应用程序本身 Contacts Create 需要身份验证 因此我想知道如何从扩展程序发送经过身份验证的请求 我已启用设
  • .NET Core 未显示在 Visual Studio 2022 的目标框架下拉列表中

    我已经安装了 NET core 3 1 并验证了我可以在我的计算机上运行 NET core 3 1 应用程序 但是当我去创建新项目时 目标框架的下拉列表仅允许 NET 6 0 我正在使用 Visual Studio 2022 我在笔记本电脑
  • ASP.NET Web 服务器无法启动并且无法切换 Mono 环境

    我在跑步Monodevelop 的最新版本之一在 Linux Mint 上 在我格式化驱动器并进行全新安装之前 它曾经可以工作 当我构建项目时 它构建得很好 但是当我尝试运行它时 我收到以下消息 无法启动 ASP NET Web 服务器 找
  • 如何在CSS中将页脚粘贴到底部? [复制]

    这个问题在这里已经有答案了 我遇到了在浏览器底部定位页脚的经典问题 我尝试过的方法包括http ryanfait com resources footer stick to bottom of page 但没有什么好结果 我的页脚总是出现在
  • HTML中点击后如何保持选择?

    我正在编写一个 WYSIWYG 编辑器 不能使用像 TinyMCE 这样的东西 必须自己编写代码 并且我希望用户能够通过在 HTML 中添加标签来将文本设置为粗体 下划线 链接等 我遇到的问题是 当用户选择可编辑 div 中的文本 然后单击
  • Bash 检查是否存在不存在的文件?

    在 bash 中运行以下命令 stuff rpm ql
  • 使用 Eclipse + ADT 创建 Android 应用程序的“最小”源文件

    我试图使用 Eclipse ADT Android 开发工具包 来了解最小 Android 应用程序的结构 请您告知我需要的最小源文件集是什么 例如 src package MainActivity java res layout acti
  • Visual Studio 中的 Typescript AMD 模块

    我从使用 Visual Studio 2012 Ultimate 的 TypeScript 开始 我已经更改了 MSBuild 包括编译器命令中的 module amd 标记 编译器开始生成AMD模块 我在我的项目中包含了来自 Nuget
  • Python:乘法覆盖

    所以 我有一个自定义类 mul 与整数一起使用的函数 然而 在我的程序 在库中 中 它被以相反的方式调用 即2 x where x是我班的 有什么办法可以让它使用我的 mul 功能为此 只需将以下内容添加到类定义中即可 rmul mul
  • 返回匿名类型的简单方法(使使用 LINQ 的 MVC 成为可能)

    我想在使用 LINQ 特别是 LINQ to entities 的同时实现 MVC 我这样做的方法是让控制器使用 LINQ 生成 或调用生成的东西 结果集 然后将其返回到视图以显示数据 问题是 如果我这样做 return from o in
  • Xkb:如何将键码转换为键符号

    我只是尝试获取 KeyCode 和修饰符掩码 并使用 Xkb 扩展将其转换为 KeySym 我似乎无法弄清楚为什么这不起作用 很明显修饰符不匹配 但我不知道为什么 我什至不知道我是否正确转换了该组 include