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
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))
...;
// ...
}
You can use this linux command to do it
{
if (num_lock == 0) system("setleds -F +num");
else if num_lock == 1) ; //do nothing
}
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.
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.
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;
}