【问题标题】:How to get a num lock state using C/C++?如何使用 C/C++ 获得数字锁定状态?
【发布时间】:2012-01-15 16:51:15
【问题描述】:

我已阅读 Gdk 论坛链接,该链接说从 3.0 版开始实现获取 num lock state api。但我使用的是 2.4 版,无法更新到 3.0 版,因为我需要支持较低的 Linux 版本。这是讨论链接:

http://mail.gnome.org/archives/commits-list/2010-July/msg00259.html

那么,还有其他方法可以使用 Linux 内部命令获取数字锁定状态吗?

问候, iSight

【问题讨论】:

    标签: c++ c linux gtk x11


    【解决方案1】:

    获取 NumLock 状态的示例代码。让foo.c成为:

    #include <stdio.h>
    #include <X11/Xlib.h>
    
    int main(void) {  
       Display *dpy = XOpenDisplay(":0"); 
       XKeyboardState x;
       XGetKeyboardControl(dpy, &x);
       XCloseDisplay(dpy);
       printf("led_mask=%lx\n", x.led_mask);
       printf("NumLock is %s\n", (x.led_mask & 2) ? "On" : "Off");
       return 0;
    }
    

    然后给出,在戴尔笔记本电脑上使用 CentOS 5 进行测试:

    gcc foo.c -o foo -lX11
    foo
    led_mask=2
    NumLock is On
    

    或者你可以用popen("xset q | grep LED");做点什么。

    掩码的第二位对于 NumLock 来说相当常见,但我不相信它是有保证的。

    原答案:一个很好的起点是xev,可以使用大约20年:

       xev
    

    您可以通过以下方式解码关键事件:

    foobar (XKeyEvent *bar) {
       char dummy[20];
       KeySym key;
       KeySym keyKeypad;
       XLookupString(bar, dummy, sizeof dummy, &key, 0);
       keyKeypad = XKeycodeToKeysym(..., bar->keycode, NUMLOCK_Mask);
       if (IsKeypadKey(keyKeypad))
          ...;
       // ...
    }
    

    【讨论】:

    • 在 led_mask 中有 capslock 和 numlock 状态,但没有 scrolllock 状态(我想知道 50 年后我们的键盘上是否还会出现那个键)。
    【解决方案2】:

    如果您不关心“什么都没有发生”的 Numlock 状态,并且仅在例如发生按键时,开销最低的方式是这样。

    对于一些XKeyEvent *xke

    bool numlock = ((xke->state & Mod2Mask) == Mod2Mask);
    

    对于 GDK,您可能需要 Gdk.FilterFunc 之类的东西来获取 xevent。检查xevent-&gt;type

    #include <Xlib.h>
    XEvent = (XEvent *) &xevent // from Gdk.FilterFunc
    int type = event ->type;
    switch(type) {
        case KeyPress:
        case KeyRelease:
            do_something_with((XKeyEvent *) event);
            break;
    }
    

    【讨论】:

      【解决方案3】:

      我做了一些嗅探,发现了一个可能的使用ioctl.h 的实现,它轮询键盘状态并针对几个标志进行测试。

      Take a look at this form post's implementation,并将K_CAPSLOCK 替换为K_NUMLOCK*。它非常丑陋,但它可以很容易地被包裹在一个函数中并隐藏起来。

      *帖子上更换的原因是因为一个老bug,大写锁定和数字锁定被意外颠倒了。 It should be fixed now.

      【讨论】:

      • 您不想在 X 中执行此操作 - /dev/tty0 可能由于权限而无法访问,并且 X 可能具有获取修饰符状态的命令
      【解决方案4】:

      我已经检查了硬件密钥代码。每当打开数字锁定并按下数字键盘上的数字键时,我都会比较所有制造商通用的硬件密钥代码。因此,我不需要使用 ioctl.h 标头。

      【讨论】:

        【解决方案5】:

        你可以用这个linux命令来做

        { if (num_lock == 0) system("setleds -F +num"); else if num_lock == 1) ; //没做什么 }

        【讨论】:

        • num_lock 的数据类型是什么,请告诉我它的初始化情况
        • 这只是您程序中的一个检查标志,用于在内部了解 numlock 的状态,因为使用 setleds 您无法接受它。设置一次后不会再尝试启用。
        • 我只需要检查状态,因为应该有一些机制可以返回布尔或整数数据类型的状态。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-17
        • 2012-12-04
        • 2013-05-15
        • 2011-07-28
        • 1970-01-01
        相关资源
        最近更新 更多