I am dealing with an issue in Ubuntu. I want to get current keyboard cursor position in terminal via Gcc
any assist...
"Terminal" is a program, or more accurately a description of a large class of programs, which implements a graphical interface emulating an external terminal (which would have been connected to your computer via a serial cable, or in some similar fashion). Your program communicates with the terminal emulator through a kind of bidirectional pipe (a "pseudoterminal") implemented by the operating system; to your program it looks like a pair of ordinary streams (stdin and stdout).
Linux itself has a terminal emulator, called "the console", which can be used instead of a window manager. Few programmers use it these days, but it's still there if you want to experiment. The console is a "terminal" (and there are usually several of them which you can switch between using a control+function key). As you might expect from the words "terminal" and "pseudoterminal", these basically look the same to your application.
There are a ton of details, which I'm skipping over because it would take a book to describe the whole thing.
The only connection between your program and the terminal (or pseudoterminal) is that you can send it a stream of characters, and you can receive a stream of characters from it. There is no other communication. There's no hidden operating system interface, because the terminal emulator is not part of the operating system. It's not even part of the window manager. It's just another userland application running without special privileges, just like your application.
You often want to do things other than just send characters to the output device. Maybe you want to clear the screen, or move the cursor to another location, or change the colour of the text or the background. All of these things are done by sending specially coded sequences interspersed with the text you're displaying. The operating system doesn't mediate or verify these sequences, and there's no definitive standard for how the terminal emulator should interpret them, but there is common framework which most terminal emulators conform to, to some extent, which makes it possible to actually write code which doesn't need to know exactly which terminal emulator is being used at the moment. The terminfo library is commonly used to describe the available terminals; by convention, the environment variable TERM contains the name of the relevant terminfo configuration, and that configuration can be used to create concrete control sequence strings suitable for the configured terminal [Note 1].
Now let's get back to your initial question: "how do I find out the current cursor location?" That's one of a small number of possible queries, which are also implemented as control sequences. Specifically, you send the terminal a control sequnce which asks it where the cursor is (usually the four characters \x1B[6n) and the terminal eventually replies with a control sequence which might look something like \x1B12,7R meaning that the cursor was on row 12 at column 7 at the moment that the control sequence was sent [Note 2]. So you could use terminfo to help you send the query and then attempt to parse the reply when it comes.
Note that the response is not synchronous with the query, since the user could be typing while the query is sent. (However, the response is sent as a contiguous sequence.) So part of the parsing process is disentangling the user input from the query response.
My guess is that you don't actually want to do all that work. In most cases, if you want to write a console application which does something less boring than just write output sequentially to a terminal window, you should use ncurses (also maintained by Thomas Dickey) or some other similar library. Ncurses takes full responsibility for maintaining the console image, jumping through the necessary hoops to communicate with the terminal emulator; one of its features is to keep track of the current cursor position [Note 3].
Another option, if you are only trying to provide better line editing and tab completion, is to use the GNU Readline library, or similar interfaces available for other operating systems.
Notes
This might or might not be the terminal you're actually using, since TERM is just an environment variable. You could set it yourself if you wanted it.
I took those codes from man 4 console_codes; another good source of information is Thomas Dickey's terse list of code sequences understood by xterm.
As far as I know, Ncurses does not use the cursor-position query to figure out where the cursor is on the screen. It maintains its own copy of the screen being displayed, which includes the current cursor position. You can use the macro getyx() to ask for what it considers the current cursor position.
Related
I have an RFID tag reader. But it works like a HID device (like a keyboard). It sends keystrokes to the computer when a tag is scanned. When I open notepad and scan a tag - it types the ID one digit at a time. Is there a way to create a program to listen to this device (or this port) and capture (intercept) all input. So that the keystrokes wouldn't appear on my system but I could assign my own events when the device sends and input. I don't want it to show up on Notepad.
I realize that the implementation can differ depending on the OS and programming language used. Ideally, I would like to make this work on both Windows and Linux. I would prefer to use something like Node.js but I suppose C could also be good.
I would appreciate any hints or pointing me in the right direction.
You could open the raw input device for reading (basically ioctl with parameter EVIOCGRAB for Linux and RegisterRawInputDevices() for Windows as discussed here and here). However, the mechanisms are quite different for Windows and Linux, so you will end up implementing all the low-level logic twice.
It should also be possible to read the input data stream from the standard input just like you would read an input from the keyboard (e.g. scanf() or fgets() in C) with some logic that recognizes when a data set (= tag ID) is complete - the reader device might for example terminate an input with a newline '\n' or null character '\0'.
You should probably do this in a separate thread and have some kind of producer-consumer mechanism or event model for communication with your main application.
I'm trying to make a simple game for the unix terminal, written in c. I've
been looking for a way to poll the keyboard, but haven't had any luck.
Currently I'm using ncurses getch() function. It works okay but if the user holds a key, the keyboard repeat will take a moment to start - also it will halt if any other key is pressed. This causes problems when playing (especially in two player mode where both games are controlled from a single input thread).
For example, if player 1 holds down 'a' and player 2 holds down 'b', I need to poll the keyboard and handle a stream of input like this:
abababababababab
As another example, if player 1 holds down the 'a' key and also presses the 'b' key, I need the input to be handled like this:
aaaaaaabaaaaaaaa
This way the simultaneous key presses don't interrupt each other. So I basically need to poll the keys on the keyboard on a set interval, and create my own implementation of a key press repeater.
Is there a way in c (with or without ncurses) to simply poll the keyboard on a time interval and read in all keys that are currently being pressed? From there I can just design the keyboard input thread to manage repeating actions manually. Basically something along the lines of kbhit, so I can check the status of a given key. But that will also let me poll the arrow keys.
It doesn't work that way:
Basically something along the lines of kbhit, so I can check the status of a given key. But that will also let me poll the arrow keys.
In any system that doesn't allow direct access to the hardware (MS-DOS is the only example you're likely to have encountered, others would include embedded systems), you're only able to read a sequence of characters (not keys) in a terminal application. GUI applications rely upon a server which does access some of the hardware (more) directly, but transforms the data.
In a terminal (such as used by ncurses), you can only check if the incoming characters includes the one that corresponds to the keyboard-key that you're interested in. Arrow keys send a sequence of characters: with ncurses you can either read the individual characters in the sequence, or rely upon ncurses to match the sequence to a known key in the terminal description.
Even with system-specific things such as the Linux console, you won't find much support for reading the keyboard as a whole: only character events. Read kbd_mode and console_ioctl to see what's available, keeping in mind this ancient caveat from the latter:
Warning: Do not regard this man page as documentation of the Linux
console ioctls. This is provided for the curious only, as an
alternative to reading the source. Ioctl's are undocumented Linux
internals, liable to be changed without warning. (And indeed, this
page more or less describes the situation as of kernel version
1.1.94; there are many minor and not-so-minor differences with
earlier versions.)
The suggested link Receiving key press and key release events in Linux terminal applications? gives some useful information. But as noted, the question (aside from the last point mentioned) is a duplicate.
I'm trying to write a C program that is able to test the performance of other programs by passing in input and testing the output without having to restart the program every time it runs. Co-workers and I are writing sudoku solvers, and I'm writing the program to test how fast each one runs by solving numerous puzzles, which could all be in different languages, and I don't want to penalize people for using languages, like Java, that are really slow to start up. Ideally, this program will start the sudoku solver program, keep it running, and continually pass in a new puzzle via stdin and test the output in stdout.
Here's pseudocode of what I want to do:
start a sudoku solver in another process
once process is running
pass puzzle string into child stdin
wait until output comes into stdout
repeat until end time limit ends
close process
I've messed around with popen, but I couldn't figure out how to write to the child process stdin. I've done a bunch of poking around the internet, and I haven't been able to figure it out.
Any suggestions on how to accomplish this? I'm running this on a Linux box. It doesn't have to be stdin and stdout for communication, but that would be the easiest for everyone else.
This is more a long comment than an answer, but your question is really too broad and ill-defined, and I'm just giving some hints.
You first need to understand how to start, manage, and communicate with child processes. An entire Unix programming book is needed to explain that. You could read ALP or some newer book. You need to be able to write a Unix shell-like program. Become familiar with many syscalls(2) including fork(2), pipe(2), execve(2), dup2(2), poll(2), waitpid(2) and a dozen others. See also signal(7) & time(7).
You also need to discuss with your colleagues some conventions and protocol about these sudoku programs and how your controlling program would communicate with them (and the evil is in the details). For example, your pseudo-code is mentioning "pass puzzle string" but you don't define what that exactly means (what if the string contains newlines, or weird characters?). Read also about inter-process communication.
(You might want to have more than one sudoku process running. You probably don't want a buggy sudoku client to break your controlling program. This is unclear in your question)
You could want to define a text-based protocol (they are simpler to debug and use than binary protocols). Details matter a lot, so document it precisely (probably using some EBNF notation). You might want to use textual formats like JSON, YAML, S-expressions. You could take inspiration from SMTP, HTTP, JSONRPC etc (or perhaps choose to use one of them).
Remember that pipe(7)-s, fifo(7)-s and tcp(7)-s socket(7)-s are just a stream of bytes without any message boundaries. Any message organization above these should be a documented convention (and it might happen that the message would be fragmented, so you need careful buffering). See also this.
(I recommend making some free software sample implementation of your protocol)
Look also into similar work, perhaps SAT competition (or chess contests programs, I don't know the details).
Read also something about OSes, like Operating Systems: Three Easy Pieces
I am writing application in C programming language that enables to monitor remote computers system information, number of logged users, free memory and so on.
I will write gathered info to standard output. But usually there will be more information then one single window of terminal, so I will need to implement some sort of 'scrolling' through results.
The easiest solution is I think to print for example first 25 rows, and then wait for user to push up or down and rewrite all rows accordingly.
Is there some easier/more elegant way to handle such output on terminal?
EDIT: forgot to mention, I would like to refresh the data if some new input comes from some remote computer, for example: number of processes changes.
Sounds like you need curses.
Here's a guide to the ncurses library.
It's an old school GUI library for terminals. Things like top and make menuconfig use it, so it's on every system. It allows you to stop thinking in terms of "print 25 lines and refresh" and more in terms of "put data in the text area which is scrollable".
Use an external pager, such as more (or less) to paginate the output. The strength of Unix is in combining simple commands, creating pipelines instead of reinventing functionality that already exists.
I am writing a chat program for my networking class and I have all the networking setup perfectly.
My problem is if a client is currently writing a message and he receives a message from a different client then his current input gets displayed with the received message.
For example if a client is writing a message "Hi there how are you?" and receives a message "Good day to you!" while in the middle of writing their message it gets displayed as:
Hi there hoGood day to you!
->w are you?
Where -> is the area for the user to type in the message. What I would like to happen is to just display the message received and have the area -> retain all the previous text that was written before the message was received.
Please make note that what the client is typing in is still in fact "there" when he receives a message. If he completes his message his full message will be sent.
Also note that my client uses pthreads. One thread to read messages from the server and display them to the users screen and one thread to read from stdin and send the messages to the server. I do believe that my problem is arising because I am using pthreads and the threads share the same stdin, stdout, stderr. Maybe this is a misconception and wrong?
I hope I have been clear on my problem. If not, sorry. Please let me know what I can clarify for you.
I started doing some research and came upon these links:
ANSI Escape Characters
Thread from Stackoverflow
I was thinking about trying to go up lines and move the cursors around and stuff, but don't know if that is the most effective way to do so. Firstly because I don't know how to capture the information that is in the terminal waiting to "entered"/sent to stdin. Maybe I just haven't found out how to do that.
Also I was wondering if there was a way to work/manipulate file descriptors to solve the problem? Maybe that wouldn't even solve it?
Thanks for reading and your time. I appreciate all your help.
Using a library such as curses to manage text 'windows' will be easier than trying to manipulate the screen by hand.
I am not an expert in unix network programming, but I am pretty much convinced that the problem is with multithreading itself rather than some stdin/stdout quirks.
What I see here is multiple threads accessing the same resource (terminal session) without any synchronization. This inevitably leads to race conditions between them.
I would recommend you to read this free e-book on sychronization problems, which is especially helpful for those who are only slightly familliar with sychronization:
http://www.greenteapress.com/semaphores/
Designate a thread as the IO thread and sent the messages to be displayed to that thread through a blocking queue (or circular buffer). Does C have those? (I use Java currently).
The problem involves threading. Your solutions are to either use one display and block the incoming message until the user finishes with the current input or use two "windows". Many conversation programs have two windows: one for incoming data (or the current conversation) and another to build the next message.
The standard C language does not have facilities for threading, windowing or cursor positioning. You'll just have to use platform specific features. Since you didn't specify your platform, you will have to look these up yourself.
By default user input is handled by the terminal itself, so a mutex alone wouldn't cut it if you want real-time updates. If you wanted a line-input mode solution you could log incoming messages and commit them every time a message is sent and before the next one is read.
Else, your best bet would be using curses as suggested. A scrollok(3x) enabled window can be used like a terminal easily using waddstr(3x) and wgetnstr(3x), no need to micromanage that if you use an IRC-like UI.
Note that using curses doesn't mean you don't have to use a mutex around your curses functions. Else, when you less expect it the screen will become full of garbage.