ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
but it returns 0 under xterm, and all of it's ilk. So I go looking and discover /dev/input/event0. I like to program in C so I knock together a little set of routines that work in loop like GTK/etc, you just call keyhandler_init(), then keyhandler_iter() every time through.
I works great. It works so good it reads ALL events, even when you hide window/change workspaces. It works like Kalashnikov, so good it's dangerous. I realize I could log in to other PC and read keystrokes of person typing at that box. I realize this is why I don't hear much about /dev/event0. This is not for civilian use. I have to teach it to watch window focus and sleep when window_id != focus_id, then wake up, clear out last event mess, and get back to work when window_id == focus_id. It needs mandatory usleep(1000) just to be reasonable.
So I have little power library of about 300 lines with a keytable lookup of about the same. I get perfect keyboard input without all that ncurses/terminfo dog and pony show. You want Cyryllic? Tweak the keytable. Klingon? ditto.
Why has this not been done yet? I can't find anything out there.
I don't think you can redefine CTRL-SHIFT-A with xmodmap to something ncurses can understand. The entries are normal, shift, mode_switch, and shift+mode_switch. Mode_switch is usually Right Alt key. Then that affects everything system wide, and I don't want to modify the whole system just so one little app can read the shift key.
All I needs is XGetKeyModifiers(display, &mods) or something like it, but I can't find the command. If you know of one, please enlighten me.
If I read XEvents, xterm gobbles up the keyboard ones before I can get to them, so all I get is what xterm didn't use.
But still, I stopped actually using ncurses years ago. I still copy the #defines and stuff because they seem kinda standard, but I stay as far away from terminfo etal as I can. Even gnome-terminal uses 'xterm' settings.
As far as screen drawing goes, you only need a few functions: term_goto(), term_printf(), term_hide_cursor(), term_color(), and term_raw(). I also have clrtoeol(), and a couple funny ones like term_graf_map() for line drawing and term_save/restore(), but they seem to use the same codes in all terminals.
How many terminfo db entries are still in common use these days? 3 or 4? "linux", "xterm*", "rxvt"...
Why did every terminal emulator think they needed to make their own custom F-Key sequences? How about the HOME/END gong show? They never work in ncurses without some special define_key() hocus pocus anyway. I'm beginning to rant
Anyway, this bypasses the issue completely and reads the keyboard directly. Scancodes are universal. No "\033[OP" and stuff anymore. Linux kernel has had /dev/input/event0 for more than a decade, so it's here to stay. I just wonder why I have no luck finding anything about it. I'd like to see how others handled the few issues I encountered.
I suggest you either create an X-application, and use every features of XKeyEvent; or create a console-application, and settle for the functions of ncurses/terminfo.
#include <X11/Xlib.h>
int main (int argc, char **argv)
{
int done = 0;
char keymap[32];
Display *mydisplay;
mydisplay = XOpenDisplay("");
while ( !done ) {
XQueryKeymap(mydisplay, keymap);
int i;
for (i = 0; i < 32; i++) {
printf("02X", keymap[i]);
}
printf("\n");
usleep (1000000);
}
return done;
}
This test code shows the keyboard state once per second. You only need to include one extra header, and use gcc -lX11. Simple.
XQueryKeymap() shows the state of the keyboard even if something else (like xterm) is gobbling key events. Just call it when you need to know, and parse keymap to your liking.
The keyboard state is returned as a 256 bitfield. SHIFT_L is byte 6 bit 2, and SHIFT_R is byte 7 bit 6.
I think I've solved my problem with a portable solution. /dev/event0 is a pain to handle too, very low level, a lot of parsing to get something usable. Now I can go back to using getc(), which is very convenient. Check getenv("DISPLAY") to see if X is running, and use this function if so, the other ioctl() if not.
XQueryKeymap() also reads keyboard regardless of window focus. So if you called it 3 or 4 times per second you could potentially get key "events" by watching the bits change, even when the window doesn't have focus.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.