How to detect when a key is press using Linux system calls - linux

I am trying to write a C program that uses Linux system calls to emulate the behaviour of the more command in the Linux terminal. Since the users might enter commands such as q to finish the execution, I am trying to find a way in which to read keystrokes from the standard inout without using read(...), as I don't want the pressed key to appear on the standard output.
In other words, I want to be able to detect pressed keys without them being written.
I have read that ioctl() and the termios struct can somehow be used for this purpose, but I am not sure how they are used (I find the man pages somewhat cryptic).
I have found a few answers to the use of those functions, but all of them seem too complicated. There must be an easier way to detect simple keystrokes, isn't there?

man 3 termios, tcsetattr, disable ECHO on stdin.
For a longer explanation see: Hide password input on terminal
Alternatively, you could go through below termios abstraction, use input layer, /dev/input/*, but I think you'll need to disable forwarding events from your input devices to upper layers then.

Related

simple keyboard event handler in D

I am trying to make a simple keypress handler that I can recycle into any program I'd like to make in D. In my search I can only really find information on how to do this in C, namely by using getch() to read characters from the command line input buffer. But I don't neccessarily want to run a program on the command line. Much like every other program in existence. I've been looking everywhere for this, even on Dlang.org , and haven't found a satisfactory answer yet.
In my specific case I'm trying to make a simple game as a project to help me learn D and I realized that I needed keypress handling so I could, at the very least, navigate menus I'd create in a more natural way so I could properly test my game.
I would eventually like this system to be usable on both windows and linux interchangably, probably just by detecting the operating system the program is running on at launch and then choosing the right code to run to make it all work. But that will come later. Right now i just want to know how to build a simple Keypress event handler that can trigger a function or method or whatever I want as soon as I press the key and have it work in a windows environment.

How can I change Linux terminal to make it look like the command "top"?

My aim is to make a program using C or C++ that prints to the Linux console in a similar way "top" does, in the sense that top's content updates and changes the existing text in the console, rather than printing new lines. How? I only want to know what are the syscalls or functions that make this possible. A little example would be very much appreciated.

How does tmux, vim, emacs, etc transcend the UI limitations of *nix terminals?

When I'm writing a program for use on the command line, I notice that there's some limitations. For instance, I can't draw a 1-pixel-thick horizontal or vertical line like tmux does when it separates panes in a window. I can only move the cursor down, not up like VI seemingly does. I can't refresh information on the top of the page if the cursor is at the bottom.
So, when programs like tmux and vi do this, I have to wonder if they are:
drawing the screen from top to bottom every update (which I think is highly unlikely because otherwise I could scroll up in my terminal and see each redraw)
using some library that enables graphics in the terminal, like SDL, which I also think is unlikely.
using some standard syscall I don't know about
or finally
taking advantage of some feature of Linux/Unix of which I'm completely unaware.
So, how do these programs generate such a rich UI in such a seemingly limited shell? So long as the answer gives me just enough fodder to go on a Google rampage, I'll be happy.
I'm also assuming that these programs use some common method to do these things, but if that's wrong let me know.
A typical terminal emulator has a lot more features than are immediately apparent.
Essentially a program just needs to output short sequences of bytes that represent various commands such as move cursor (up|down|left|right), change color, scroll region, erase region, etc.
These commands typically begin with the escape character (the same character that is generated when you press the esc key while typing in a terminal) followed by various other characters, depending on which action is desired.
A good starting point for understanding how it works would be the Wikipedia Article about ANSI escape codes
You can do it by hand by putting the terminal into raw mode and writing directly to the terminal using low-level operations but the standard way to do it is to use the ncurses library.

Lua: Get Keyboard Input Without Blocking

I've started working on a little project in Lua that involves making a text-based interface that updates constantly, and allows keyboard input for interaction.
I need a way to get keyboard input, but I also need it to either not block, or have some kind of timeout (which can be set to a fraction of a second, preferably). I've done research myself, but I found nothing that worked for me.
I need something that works with Lua 5.1.5 and Linux. Windows compatibility would be nice, but is not a requirement as I'm also doing things that require an ANSI terminal.
As stated in the comments of my post by hyde, I can use a Lua wrapper for ncurses to get input. In addition to this, I can use its features for some other parts of my code that I was going to program myself anyways.
I'm doing this in Lua 5.1 with Luasocket and opening two separate Lua processes. I have two Lua console windows- "INPUT WINDOW" AND "OUTPUT WINDOW". INPUT WINDOW sends keypresses over localhost. OUTPUT WINDOW reads the localhost socket I'm using for this. It's non-blocking; you can set a very quick timeout on the udp receive. It's ugly, but it's the most vanilla solution I've found. That said, input data from INPUT window doesn't appear on the OUTPUT window (unless I want it to), which can be nice for a console-based UI.

Printing in color from printf(9)

Is it possible to print to console in color from the kernel's version of printf? Can I see the same escape codes that I can in userland? Does the kernel understand the console well enough to be able to provide termcap style APIs and constants for specific color? If so, which header are they defined in?
You can certainly print arbitrary escape sequences from kernel. It would happily put whatever bytes out on a terminal. Whether those bytes would be interpreted as color, kernel, generally speaking, has no idea.
So, it is possible to print and you can see the same escape codes once you read kernel messages (i.e. if kernel prints XTERM-style colors and you happen to look at them via serial port with a terminal program that either uses XTERM or emulates XTERM escape sequences itself)
As for whether kernel knows much about your terminal type and able to use termcap info, the answer is, in general, no.
In userland terminal type is a matter of convention. Login script tries to figure out what kind of terminal you may be connected to and then sets TERM to appropriate type in the shell's environment. Forked processes inherit it and use the type in order to figure out how to do certain things on specific terminal. Usually it involves some sort of curses library.
Kernel, on the other hand is fairly minimalistic beast that does not really give much of a damn what's on the other end of whatever happens to be its console -- serial port, firewire or video card. For all practical purposes, console may not even be connected to anything at all.
Practically, you will need to solve two problems:
Have a way to configure terminal type for particular TTY device you want to use.
Provide kernel with som sort of termcap/terminfo data for that terminal type and an API to produce appropriate escape sequences for output on specific TTY. In other words -- in-kernel curses library.

Resources