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

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)

Related

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.

Linux terminal - printing lots of data

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.

Getting a pointer to my XDisplay (Linux) (X)?

I need to be able to access the X Event Loop to add clipboard support for a game API. The problem is the game API does not know which API it will use for display (It could use SDL or other). As a result, I do not have direct access to the X event loop. Is there a function in XLib to get a pointer to my display so that I can process messages and add clipboard support?
Thanks
If it runs on X11, there has to be a Display pointer in the graphics object somewhere. You can allocate a new one with XOpenDisplay(NULL); but that's not likely to achieve what you want. You'd still have to find the Windows and other info which is tricky enough when a program does it once.
You really need to dig through the existing code to find the X11 module. There's likely to be a single function that performs on iteration of the "Event Loop" as a subroutine of the real "main Processing Loop". If you can't simply add your new code there, you can at least see how the program already accesses this information.
If you're using OpenGL for graphics, you can exploit that. At some point in the program where you know, the OpenGL context is made current call glXGetCurrentDisplay. However you should be carefull not to interfere with the programs main event loop.

C - going from ncurses ui to external program and back

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!

Resources