in Gnome/metacity can we bind a key to a command that requires user input from the keyboard? - c

All,
I have a little utility written in C that requires the user to press a key to make a menu selection. The code is predictably simple:
system("stty raw");
save_ID = getchar();
system("stty cooked");
It grabs the keystroke and doesn't need to wait for ENTER. It works fine from the command line, however, when I try to bind the command to a hotkey in Gnome/metacity, it waits for the keystroke alright, but the keystroke seems to be processed not as as input to the command, but as if it were a separate command. Eg. if my keystroke is "1" and I'm in a terminal I see:
"zsh: command not found: 1"
I've tried it without the "system" lines, but nothing changed. Is there perhaps some special version of "getchar" that works with the GUI? Incidentally, a non-interactive version of the program works fine when bound to a hotkey, so the program is basically functional, it just can't be used interactively.
Thanks

I believe GTK may interest you, although I've never personally used it.
http://www.gtk.org/
.
You should also be able to run gnome-terminal. Using /opt/appFoo/appFoo as the command to run your app normally, you would run
gnome-terminal -e "/opt/appFoo/appFoo" &

Related

How do I make a C executable for Windows written on Linux not close the cmd as soon as it finishes running?

So, I've written a C executable on Linux for Windows using mingw32-gcc. It is a basic Input-Output program, you type an input and get an answer.
Problem is the cmd shuts down immediately, so the user can't see the output.
Assuming I cannot use Windows to edit the executable there, what should I change in my code/ what flags should I use when compiling it?
inb4:
the user is supposed to click and run it, so running it from cmd won't help.
adding getchar()/scanf() at the end of my code doesn't work, and it feels a bit like cheating.
SOLVED: so all I had to do was to actually add a getchar() after every scanf() and one more at the end of the code for the user input to close the cmd.
Waiting for input at the end is not cheating, but common practice. How else should program know for how long it should stay opened? Closing program by closing console window directly is more cheating than waiting for user input to finish.
You can for example prompt user to hit any key like Press any key to exit... or something similar.
If you want some specific delay, you can use Sleep() from windows.h instead of waiting for input.
See https://stackoverflow.com/a/3379146/3035795

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.

Reset after using system call (stty raw)

I am using the following code to read and output each keystroke without having to press enter each time.
system("\bin\stty raw");
Right after I finish reading, the program does another system call to reset the terminal behaviour.
system("\bin\stty cooked");
The thing is, the last line is not resetting the terminal behavior as it should. Everything gets messed up once this program terminates. It continues to read input and does not do anything once an enter or CTRL C or anything else is pressed.
How can I reset the terminal behavior to the one it initially was please?
Use popen() and pclose() to run "/bin/stty -g". Read the output from stty -g] and save it for later.
When you want to reset the terminal, use "/bin/stty the-string-from-stty-g".
The mechanics are fiddly but doable.
The whole point of the -g option to stty is to give a string that can be passed back to stty to reinstate the current settings. You can then run your stty raw, ensuring that you reset the terminal before you exit using the string from stty -g.
Note, too, that stty sane does a good job of resetting aberrant terminals to a known state. You may need to run: Control-Jstty saneControl-J at the terminal command line to make it work.
You can also do it without running external programs. You'll need to look at tcgetattr() and
tcsetattr() and related functions. Again, you read the current settings (tcgetattr() et al), change a copy of them and set those as the new values, and ensure that you reset the original settings on exit (maybe with atexit()?).

stty RAW console in C

I'm trying to build my own console and I'm using the below statement to get RAW access so I can implement some advanced features such as implementing the auto suggest feature that's implemented in a BASH shell by pressing the TAB key.
system("/bin/stty raw")
When using this, the enter key (and others) doesn't behave normally and when I press enter, it displays ^M and doesn't go to the next line.
How do I set the RAW console to go to the next line when it receives ^M
Also can I set the Shell to NOT display the keys pressed so I can send the char back to the console with putchar() (so ^M doesn't display when pressed).
Thanks
How do I set the RAW console to go to the next line when it receives ^M
You write an appropriate control code to the console when you read an ^M. The whole point of raw mode is that the console does not do things like recognize line ends, backspaces, etc., etc., because you want to handle them yourself. Once you do that, you need to handle all those things.
can I set the Shell to NOT display the keys pressed
Sure. Turn off echo. With the stty command, you would use stty raw -echo but if you're doing this from a C program, you'd be much better off using the terminal API. See man tcsetattr

Why does the terminal show "^[[A" "^[[B" "^[[C" "^[[D" when pressing the arrow keys in Ubuntu?

I've written a tiny program in Ansi C on Windows first, and I compiled it on Ubuntu with the built-in GCC now.
The program is simple:
read the line from console with scanf().
Analyze the string and calculate.
But something weird happens. When I try to move the cursor, it prints four characters:
pressing Up prints "^[[A"
pressing Dn prints "^[[B"
pressing Rt prints "^[[C"
pressing Lt prints "^[[D"
How can this be avoided?
Why does it print these 4 characters instead of moving the cursor?
Because that's what the keyboard actually sends to the PC (more precisely, what the terminal prints for what it actually receives from the keyboard). bash for example gets those values, deciphers them and understands that you want to move around, so it will either move the cursor (in case of left/right) or use its history to fetch previous commands (up/down). So you can't expect your program to magically support arrow keys.
However, reading from standard input from the terminal already supports left/right arrow keys (I believe, but I'm not in Linux right now to test and make sure). So my guess is that there is another issue interfering. One possible cause could be that one of your modifier keys is stuck? Perhaps ALT, CTRL or SUPER?
For those who are coming from the osx (mac) try changing the shells to bash
Terminal -> Preferences -> Shells open with -> [select] Command (complete path)
then paste
/bin/bash
This might be because the user account is created in shell. You can change it to bash by two ways.
Permament solution is -
sudo chsh -s /bin/bash ${username}
To get this solution working you will have to logout and login
Temporary solution is everytime when you login into the ubuntu server type bash and hit return.
If it's under a docker container, run /bin/bash . This helped me solve the problem.
Additionally to what Shahbaz mentioned, I realized that pressing enter (thus sending an empty command) can fix the problem. This is usually necessary after using CTRLC to cancel a command.
On MacOS Terminal for me was enough to uncheck "Scroll alternate screen" for the issue to disappear. See screenshot of the preferences below.
You can (re)bind keys. Add this at the bottom of your .profile, .zshrc or whatever shell config you have.
bindkey -e
bindkey '\e\e[C' forward-word
bindkey '\e\e[D' backward-word
i think simple way is we can just do
kill %%
because this sometimes happen because of background processes.

Resources