Delete current terminal input line - c

I am trying to code a little console chat-program in C on linux.
So far I coded it in a way that both chatting partners are only able to alternately send/recv, because these function calls are blocking by default.
Now I would like to modify that program, so that both are able to send and receive simultaneously.
The problem that I find is, that once you typed some input to the terminal, I don't know how to output received messages, without messing up the current input line of the terminal.
If there was a way to delete that current input line, you could temporarily save that line, print the new message and put the input line right back.
However, I was not able to find a solution for this problem on the internet.
Is it possible to delete the current input line, and if not, how else could I achieve what I want?

I think you should look into ncurses as Edd said in his comment.
It would allow you to easily manage contents in your terminal window, which sounds like a good idea for your chat program.
All you'd need to do is store your messages in 2 character arrays:
char incoming[MSG_MAX]
and
char outgoing[MSG_MAX]
Then you can output those messages wherever you want in your terminal window, since ncurses allows you to specify x,y coordinates on where to put your text.
Then a simple wrapper for one of ncurses erase() family functions would allow you to delete characters from specify x,y coordinates in your terminal window.
Edit: MSG_MAX is not an actual ncurses macro.

Related

Resizing output Terminal in C Language

would like to get some help on a c project i am currently working on. I have a string/array of output to the terminal, but somehow the standard terminal is too small for my output. Even after i manually expand the window of the console the output is still cut off, instead of printing in a single line, it just gets cut off and go to the next row automatically.
hope to get help.
I think that the only way to correct this is by splitting your one-line output in multiple lines, using "\n" at the end of every line.
By doing this you can control when and where it has to write in the next line, and you can make it look more like you wanted to.

Stopping Linux console from echoing input during program execution

I'm writing a C program that requires to hide the characters a user types from the screen during the program execution. For example, when running the following loop
while (1)
{
//do some work
}
the console displays the blinking cursor (that's good). BUT, when the user types keys on the keyboard, these keys are being echoed out to the console. To visualize it better:
Step 1: Starting the program
root#debian:/home/root# ./program
_
Step 2: User types some characters (even though he shouldn't)
root#debian:/home/root# ./program
AdajfsaSJ_
The characters get echoed on the console. How can I stop this? I know it's theoretically possible, but I can't find out how to implement it.
If you need a better example for what I want to achieve, use the screen command on an empty serial port. screen /dev/tty30 for example. This empties the console and runs the program, HOWEVER, the user is not able to enter any characters (there's a blinking white cursor block and no keyboard characters are being echoed to the console). That's what I need.
Any insight would help, thanks!
Use termios() to turn off the ECHO flag of the terminal.
To turn off the text cursor, use the termcap library to control the cursor visibility.

Stable text feed for vim through vimserver

I am searching for a highly stable way to feed text (output of a program) into vim through vimserver. Assume that I have started a (g)vim session with gvim --servername vim myfile. The file myfile contains a (unique) line OUT: which marks the position where the text should be pasted. I can straight forwardly achieve this from the commandline with vim --servername vim --remote-send ':%s/OUT:/TEXT\\rOUT:/<Enter>'. I can repeatedly feed more text using the same command. Inside a C-program I can execute it with system(). However TEXT which is dynamic and arbitrary (received as a stream in the C-program) needs to be passed on the command line and hence it needs to be escaped. Furthermore using the replacement command %s vim will jump to the position where TEXT is inserted. I would like to find a way to paste large chunks of arbitrary text seamlessly in vim. An idea is to have vim read from a posix pipe with :r pipe and to write the the string from within the C-program to the pipe. Ideally the solution would be such that I can continuously edit the same file manually without noting that output is added at OUT: as long as this location is outside the visible area.
The purpose of this text feed is to create a command line based front end for scripting languages. The blocks of input is entered manually by the user in a vim buffer and is being sent to the interpreter through a pipe using vim's :! [interpreter] command. The [interpreter] can of course write the output to stdout (preceded by the original lines of input) in which case the input line is replaced by input and output (to be distinguished using some leading key characters for instance). However commands might take a long time to produce the actual output while the user might want to continue editing the file. Therefore my idea is to have [interpreter] return OUT: immediately and to append subsequent lines of output in this place as they become available using vimserver. However the output must be inserted in a way which does not disturb or corrupt the edits possibly made by the user at the same time.
EDIT
The proposed solutions seem to work.
However there seem to be at least two caveats: * if I send text two or more times this way the `` part of the commands will not take me back to the original cursor position (if I do it just once still the markers are modified which may interrupt the user editing the file manually) * if the user opens a different buffer (e.g. the online help) the commands will fail (or maybe insert the text in the present buffer)
Any ideas?
EDIT: After actually trying, this should work for you:
vim --servername vim --remote-send \
":set cpo+=C<CR>/OUT:<CR>:i<CR>HELLO<CR>WORLD<CR>.<CR>\`\`"
As far as I can see, the only caveats would be the period on a single line, which would terminate :insert instead of being inserted, and <..> sequences that might be interpreted as keypresses. Also, need to replace any newlines in the text with <CR>. However, you have no worries about regular expressions getting muddled, the input is not the command line, the amount of escaping necessary is minimal, and the jumping is compensated for with the double backticks.
Check out :help 'cpoptions', :help :insert, and :help ''.
Instead of dealing with the escaping, I would rather use lower-level functions. Use let lnum = search('^OUT:$') to locate the marker line, and call setline(lnum, [text, 'OUT:']) to insert the text and the marker line again.

simultanous read and write (stdin, stdout) in C

I'm trying to write a chat client and server and the client should be able to print the messeges from the server while also writing something on the console.
So I created a pthread that should read the user input and the main thread prints the messeges from the server. But when I type something and while typing a messege is received, the text I was typing is pushed up on the console. How can i fix that?
for example:
I'm typing "abcdef" and then when I get a messege from the server (but didn't finish typing yet) it will look like this:
abcdef[Chatuser1]:Hello
Use synchronization technique like semaphore or mutex to synchronize input and output in your multi threaded program
I would really recommend doing something like this in a GUI with two seperate edit box elements and not in a console.
If you still want to do it in a console, you will need to do direct console buffer modification.
Every time a new output message arrives, the current input message has to be backed up so you can savely write to the console then do some custom scrolling and add the input message back again. Thread syncronisation is needed to prevent mixing of input and output in the buffer.
I think you also would not get around custom key handling, because otherwise you have no access to partialy typed input.

How to read from keyboard when stdin is set to a file in C

I think this is simple, but not for me obviously!
I have a console-application. I need to read input from the keyboard, but stdin has been redirected to a file. So how do I create a FILE-Handle that points at the keyboard-stream which i can use with fgets etc.?
I found out that ttyname(0) seems to be what i look for in a POSIX-environment, which I don't have here. I'm in a Windows-system with standard Visual Studio compiler.
Any ideas? Thank you in advance.
There's no easy/portable way to tell if a keyboard exists (your application may be being run from a terminal emulator from a serial port, a telnet session or anything else). If a keyboard actually does exist (including a picture of a keyboard on a touch screen), then you can't really tell how many layers of software the keystrokes need to pass through before they get to your application (e.g. keystrokes might go from a keyboard driver to an input method editor to a GUI to a shell to your application). This means that attempting to get keystrokes directly from a keyboard driver or something is a bad idea that will fail in almost all cases.
The best way to solve your problem is to find out which series of design failures led to STDIN being redirected in the first place.
For example; maybe the application should've had a command line option to read some data from a file; so that the application can get some data from the file and some from STDIN (and get all data from STDIN if the command line option isn't present).
Pulling from the dim dark days of DOS programming here: try opening "CON:" (Console), a reserved word. Hopefully it will open the same way in Windows. The colon may or may not be required. Both "dir >con:" and "dir >con" still work in command prompt.
Also, be sure to use something from the setbuf() family on the output handle to avoid buffering... it's not supposed to buffer terminal I/O, but it never hurts to be sure.
Again, not sure, but I suspect opening separate FILE *conin, *conout for output and one for input may help if you seem to have troubles with one handle doing both input and output.

Resources