How to get a num lock state using C/C++?

2019-03-31 18:27发布

I have read Gdk forum link which says that getting num lock state api is implemented since version 3.0. But I am using version 2.4 and I cannot update to version 3.0 as I need to support lower Linux version. Here is the discussion link:

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

SO, is there any other way to get the num lock state using internal Linux command?

Regards, iSight

标签: c++ c linux gtk x11
5条回答
女痞
2楼-- · 2019-03-31 18:49

If you don't care about the Numlock state "while nothing is happening", and only when e.g. a keypress happens, the lowest overhead way is this.

For some XKeyEvent *xke

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

For GDK, you might need something like Gdk.FilterFunc to get the xevent. Check xevent->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;
}
查看更多
Anthone
3楼-- · 2019-03-31 18:51

I have checked the hard ware key code. Whenever num lock is on and pressed the number key at num pad i compare the hard ware key code which is universally constant to all manufacturer. Hence, I don't need to use ioctl.h header.

查看更多
Emotional °昔
4楼-- · 2019-03-31 18:54

I did some sniffing around, and I found a possible implementation with ioctl.h that polls the keyboard state and tests that against a couple of flags.

Take a look at this form post's implementation, and replace K_CAPSLOCK with K_NUMLOCK*. It's pretty fugly, but it can easily be wrapped in a function and tucked away.

*The reason for the replacement on the post was because of an old bug where caps lock and num lock were accidentally reversed. It should be fixed now.

查看更多
Viruses.
5楼-- · 2019-03-31 18:59

You can use this linux command to do it

{ if (num_lock == 0) system("setleds -F +num"); else if num_lock == 1) ; //do nothing }

查看更多
戒情不戒烟
6楼-- · 2019-03-31 19:11

Sample code to get the NumLock state. Let foo.c be:

#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;
}

Then this gives, tested with CentOS 5 on a Dell laptop:

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

Or you could do something with popen("xset q | grep LED");.

The second bit of the mask is fairly common for NumLock, but I don't believe it is guaranteed.

Original answer: A good starting point is xev, available for about 20 years:

   xev

And you can decode key events via:

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))
      ...;
   // ...
}
查看更多
登录 后发表回答