C - going from ncurses ui to external program and back - c

I'm making a program that displays some info in ncurses, and then opens vim (using system) to allow the user to edit a file. After vim is exited, though, the ncurses screen won't redraw. refresh and wrefresh don't do anything, resulting in the complete trashing of my beautiful menu.
So, I get sent back to the command line. The menu items redraw when I move to them. Moving around a bit results in something that looks like this:
As you can see, I no longer am in my pretty ncurses environment,.
I could tear down ncurses completely and set things up again, but then some stuff (like menu position) is not preserved.
How do I do this correctly? Is there a better way to call some external program and return here gracefully?

I've never had to restart curses entirely.
what if you do something like
def_prog_mode() then
endwin()
execute system call
and refresh() should restore it

Separate your program state from the curses state.
The only clean way I know of is to stop and restart curses entirely. If your program has a clean notion of its internal state (as it should), then it should be easy to go back to the same position.
Good luck!

Related

Asynchronously exit loop via interupt or similar (MSP430/C)

I have run into a problem that I am rather stumped on because every solution I can think of has an issue that makes it not work fully. I am working on a game on the MSP430FF529 that when first powered up has two images drawn to the screen infinitely using a loop and cycle delays. I would like to have it so that when the user presses the start button (a simple high-edge trigger on a port) that the program immediately stops drawing those screens, no matter what part of the process its in, and starts executing the rest of the code that runs the game.
I could put the function that puts the images on screen in a do while loop but then it wouldn't be asynchronous as the current image being drawn would have to finish before it moved on.
I'd use the break command but I don't think that works in ISRs and only when its directly in the loop.
I could put the entire rest of the program in the ISR I use for the start button press so that the screen drawing is essentially never returned to but thats really messes, poor coding, and would cause a lot of problems later.
Essentially, I want to make it so that when the button is pressed the program will immediately jump to the part of the program that is the actual game and forget about drawing those images on the screen. Is it possible to somehow have an ISR that doesn't return to what was currently happening after the code in the routine is executed? Basically, once the program starts moving forward (the start button is pressed) I don't want to come back to the function that draws the images unless I explicitly call it again.
The only thing I can think of is the goto command, which I feel in this particular instance would not actually be too bad, though I want to avoid using it for fear of it becoming a habit due to it being a poor solution in most cases. However, that might not even work because I have a feeling that using goto in a ISR would really mess up the stack.
Any ideas? Any suggestions are appreciated.
What you want is basically a "context switch". You should modify the program counter pointer and stack pointer which will be restored when you return from the ISR, and then do the normal ISR return so the interrupt mask is cleared, stack is restored, etc. As noted in the comments to your question, this likely requires some manual assembly code.
I'm not familiar with the MSP430, but on other architectures this is in a structure of saved registers on the kernel stack or interrupt-context stack (or maybe just "the stack" on some microcontrollers), or it might be in some special registers, and it's saved automatically by the CPU when it jumps to your ISR. So you have to change these register pointers where they are.
If you relax your requirement from "immediately" to "so fast that the user doesn't notice", you can put the if (button_pressed) into some loop in the image drawing routine.
If you really want to abort the image drawing immediately, you can do so by resetting the MCU (for example, by writing a wrong password to the WDT). In the application initialization code, check if one of the causes of the reset was your own software:
bool start_button = false;
for (;;) {
int cause = SYSRSTIV;
if (cause == SYSRSTIV_WDTKEY)
start_button = true;
if (cause == SYSRSTIV_NONE)
break;
// you might handle debugging of other reset causes here ...
}
if (!start_button)
draw_images();
else
actual_game();
(This assumes that your code never accidentally writes a wrong WDT password, but even if that happens, you're only skipping the intro images.)

Adding keyboard shortcuts in my homemade shell

So I have to write a basic shell in C for school, no pipes, no redirections, I just have to execute the binarys and code a few builtins.
I already did most of that, but now I would like to implement some keyboard shortcuts, like ctrl+L to clear the screen, up/down to navigate through commands history, ctrl+D to exit the shell and so on.
The problem is, I have no idea how to read input without the user pressing enter.
Also I should mention that I can only use a very limited panel of functions, the only function I can use to read input is the system call read().
If anyone has an idea it would be great
Generally use the readline library to read input. It supports defining shortcuts, history, auto completion, ... and is meant for that purpose.
If you are not allowed to use it, I guess your teacher wants you to concentrate on important parts of the task rather than getting fancy.
If you just want to play around a bit, you may start your shell using the rlwrap command:
rlwrap your_shell
rlwrap can be used to add readline functionality to arbitrary commands which read from stdin.

Cocoa system() progress?

I am creating an application that must use the system(const char*) function to do some "heavy lifting", and I need to be able to give the user a rough progress percentage. For example, if the OS is moving files for you, it gives you a progress bar with the amount of data moved and the amount of data to move displayed on the window. I need something like that. How can this be done?
Edit: Basically, I give the user the option to save files in a compressed format. If they do so, it saves normally then runs this code:
char* command = (char*)[[NSString stringWithFormat:#"tar -jcvf %#.tar.bz2 %#", saveurl.path, filename] cStringUsingEncoding:NSUTF8StringEncoding];
system(command);
Sometimes this takes a little while (the app deals with video files), so I want to be able to give them an estimated completion time.
I am creating an application that must use the system(const char*)
function to do some "heavy lifting"
No, it doesn't have to use system() as such. In fact, it shouldn't. There are plenty of other APIs for running subprocesses, almost all of which will be better. In Cocoa, the most obvious better option is NSTask.
In any case, there's nothing that can tell how much progress a subprocess is making except that subprocess itself. If the program you're running doesn't provide a means for reporting progress, there's little hope. Nothing else can even divine what the purpose or goal of the subprocess is, let alone judge how far along it is to meeting that goal.
Even if the program does report progress, you'll need a means to receive that information. system() doesn't allow for that. NSTask does, as would popen() or manually forking and execing the program.
You would need a command line program that has a way of communicating progress information back to your application (or perhaps simply write progress info to a log file that you parse in your cocoa app). Are you sure you really need to do this?
For your edited example, you might consider just putting up some sort of spinner or hourglass type UI indicator to show them that the write is in progress, while allowing them to continue with other work. You can't predict archive creation time, especially when you add compression to it.

How to get a character while inside a loop without stopping in the loop?

Hello I am new to C programming but I am making a menu for a game. I have a fish in ascii art displayed and it gets moved one character over every .5 secs. I accomplish this by a simple loop and it keeps on going across the screen then when it reaches the end, the fish is cleared and then it gets repeated again. Now while this animation is going on I would like to prompt the user for an input, however when I do that with getchar or scanf for example the fish loop waits until I press something and the animation stops until I press a key. Coould someone please shed some light on my problem??
Thank-you
You can't do this with any of the standard input methods. You're going to either have to use something like ncurses, or put the terminal into raw mode and do some pretty fancy manipulations. I have no idea what platform you're on, but raw mode is difficult under Linux, and even harder under Windows, so I'd stick with a library if you can.
Welcome to the world of Threads.
To understand threads think of how your computer works. If your computer ran without threads, you would not be able to run multiple applications at the same time. Threads allow for multiple parts of a program or interface to run at the same time without depending on eachother.
In your case, you will want a thread for the input and a separate thread for the animation. Thus allowing both to run separately.

How to grab 'key-press-event' when the window is not focused?

I am writing a program using gtk. What the program does is monitor the keystroke the user entered and play a sound. My question is that how do I catch the key-press-event when the window is not focused? I'm planning to let my program stay in tray icon, so I wonder how I can grab any key-press-event from there. Thanks
Edit:
I finally find a way to do it - The XTest extension, I found the a piece of code snippet from the program 'xmacro'.
You can see my implementation here:
http://github.com/Aitjcize/Qwertickle/blob/master/src/qwertickle.c
btw, it's still quite buggy, maybe someone can help me out? :)
As Matt Joiner said,
This kind of thing isn't as easy in Linux.
and unfortunately GTK+ can't do this kind of magic.
You should take a look at XEvIE - X Event Interception Extension - it will make your job easier.
XEvIE is a X extension providing functionalities to allow users intercept keyboard/mouse events.
And as suggested by this guy, another way to go would be to use XGrabKey()/XUngrabKey() from X11. I believe that tinywm shows how to use it correctly.
There is a program called xbindkeys that can bind mouse and keyboard keys in X to launch shell commands. You can either utilize this to send commands to your program, or look at the sourcecode to see how its done: xbindkeys
You can also directly open /dev/input/eventX and read() from it to an input_event struct, but thats a little nasty, because you need to have the proper rights (normally root, or change it with chmod)

Resources