Forwarding ncurses key events to an X11 window - c++

My application's user interface consists of two windows: the console (handled by ncurses) and an X11 window for graphics. I would like to handle key events in a centralized way. That is, no matter which of the two windows is active, the same event loop should handle all the key events. I already have an event loop for X11 events. All that remains to be done is to forward all the console events to the X11 window.
The main building block to achieve this forwarding is found here. The only other thing I need is to be able to translate from the value returned by getch() to X11 keycode. After about four hours of searching the web, I found this code, which is part of qemu. However, when I compare the mapping it provides with the output of xev, the two do not match. For example, for the Home key, xev gives 110, while the mentioned mapping gives 71 | 0x0100, which is 327. Are these two different kinds of keycodes? What am I missing?

Hmm, mixing application frameworks is, almost by definition, difficult.
I think the best way to achieve what you want is to have two separate processes or threads, one for the console and the other for the X11 application. In each you would have the relevant event loop handler. To join them together use an IPC channel, either a pipe or socket. You should be able to make the socket/pipe an input to the X11 event loop handler with its own callback. You can have a select() on the console side waiting on the socket or STDIN; this allows you to call getch() when there's a keypress ready or read from the socket when the X11 has sent something through the socket. If you used something like ZeroMQ in place of the socket, even better.
So, what would you send through the socket? You would have to define your own event structure to pass between the console and the X11 application. Each side would populate and dispatch one of these when it needs to send something to the other. The types of event you'd need to describe would include would be things like quit, keypress (+ keypress data), etc.
Most likely you'd arrange the X11 end so that the socket reading callback read the structure from the socket, interpreted it and decided what callback should then be called directly. If your key presses are only for selecting menu entries, buttons, etc then this might be a not-too-bad (but not brilliant) way of avoiding the mapping problem.
This does mean having two event loop handlers, a socket and two processes/threads. But it does avoid blending the two into a single thing. It also means your console could be on a completely different machine! If you had used zeromq you could easily have multiple consoles connected to the X11 application in a PUSH/PULL configuration; perhaps absurd, but possible.

Related

Use select() with a non-file-descriptor-based input

To my knowledge, the select() function in C can only wait for file descriptors to become active (i.e. for reading them to not block.)
This is useful for a command-line messaging application since everything will be either a socket file descriptor, or stdin.
However, what if I want to incorporate this with a GUI application (for example, one written in Gtk?)
I assume there's no way to tell select() to wait for a button to be pressed, right? So will I have to use multithreading?
If you want to incorporate non-fd activity into a select-based event loop (or other fd-related alternatives like epoll), you can do that by using a pipe. The action triggered by the event (such as a button press) writes a description of the event into the pipe, and the select mask includes the read end of the pipe, so it will be notified of the data availability.
If the events and the handlers are in the same process, it's not necessary to fully serialise the event description, since some other mechanism could be used (a in-memory queue of events, or some such). However, since most events can be easily and efficiently described in a few bytes, serialising the event provides an easily scalable architecture.

Hook and block globally mouse in X11

I need to hook globally mouse clicks and block last click if delay between two clicks is less than was set.
I wrote it for windows using WM_MOUSE_LL hook.
I was unable to find any solution for me. Is it even possible to globally block mouse click in X11 ?
Windows full code
As far as I know the standard X11 protocol doesn't allow this. The XInput 2.0 extension might, but I doubt it.. while Windows assumes a single event queue that every program listens to, so that a program can intercept an event and prevent it from being sent down the queue to other listeners, every X11 client has its own independent queue and all clients that register interest in an event receive an independent copy of it in their queue. This means that under normal circumstances it's impossible for an errant program to block other programs from running; but it also means that, for those times when a client must block other clients, it must do a server grab to prevent the server from processing events for any other client.
Which means you can either
use an X server proxy (won't be hard, but will be pretty slower)
or
do it on the input device level. /dev/input/event<n> give you the input events. You can read off the keypresses there and decide if they should propagate further be consumed. Unfortunately there's no real documentation for this, but the header file linux/include/input.h is quite self explanatory.

Read raw input in Linux in non blocking way

I'm doing some research on the Linux kernel, particularly the input subsystem. I'm interested in reading /dev/input/eventX device(s) for different input events (mainly keyboard and mouse).
However the read() operation blocks. The only thing I can think of is creating a state of all the keyboard keys and mouse buttons, and then create a new thread for reading keyboard and mouse states (those threads might be blocked from time to time), and from my main process, access the state of the keyboard and mouse.
However, I'm not very experienced in non blocking programming under C++ and Linux and I think that a thread for each device might be an overkill.
I'd like to know if there are other ways to handle input in non blocking way, or using threads is fine?
Thanks, skwee.
You can check out the poll system call for this. Is for handling I/O on multiple file descriptors. One possibility would be to spawn only one thread to poll for events on multiple file descriptors.
Here is some reading material : http://www.makelinux.net/ldd3/chp-6-sect-3
You can set the file description to non blocking. You can also use select/poll to check to see if data is available to be read in which case you don't need non blocking. See this thread;
Non-blocking call for reading descriptor

How to send system events from driver to application layer?

I'm writing a driver for a device with Windows Embedded Compact 7 OS, in which applications written in .NET 3.5 will be running. My requirement is that, I need to send some custom defined system events (for some conditions that occurred in the driver) to these applications so that the corresponding event handlers written in the application should be executed when an event is invoked.
So,
What should I do to invoke/raise such events?
Which function is to be used?
How do a system event differ from a message?
How to add Event handlers in a .NET application?
TIA.
Using the plain win32 API, I would create a named event (i.e. supply a name for CreateEvent()). This can be use across process boundaries, including across the kernel/userspace boundary. You would then simply use WaitForSingleObject() and related functions to check the event state.
If you have a stream driver, you can also call ReadFile() from the application and simply stall inside the according handler function of the driver. This makes it pretty easy to add data to the event, too. Further, it provides separation between different processes that access the driver, or even different instances within the same process. Compare this with the event above, which is effectively system-wide visible and can also be set by different processes, although you can restrict this to some extent.
Another alternative is to use window messages (PostMessage(), SendMessage() etc) which also work across process boundaries. I'm not sure if this works from the kernel though. These would then end up in the "normal" message queue of e.g. the applications main window or any other window you previously told the driver. Compared to the other two approaches, you need a window as target, so it only works one way, and you don't know where a message came from.

Multiple Raw Input Window Sinks

I have a message-only window (ATL::CWindowImpl) that registers itself for raw input using the RIDEV_INPUTSINK flag, meaning it gets all input regardless of whether the window is the foreground window. This works great when there's only one instance of that window.
However, when I create more than 1 instance of my window, only one receives the WM_INPUT messages (I'm currently creating two, and only the second one to be created gets the messages).
RegisterRawInputDevices (using RIDEV_INPUTSINK | RIDEV_NOLEGACY) is succeeding during the creation of both windows. Also, the window not receiving raw input is still receiving other messages, so it's not a problem with the window itself...
If it's relevant, I'm using the VC11 beta, and windows are created and dispatching messages on different threads (using std::thread).
Is this an API limitation (i.e. you are limited to one input sink per process)? Or is there a way to get this working?
Thanks in advance.
EDIT:
Right now my current workaround is to just have one window and for it to pass on the input messages to the other windows, however this is a mess, and won't work in the case I want it to work in (where I have my app loading plugins which may want raw input, I don't want them to have to register with my app unless I really have to do it that way...).
From MSDN (here and here) the whole API for Raw Input talks always about application and not about window... which means that an application registering for raw input will be trated by the OS as one entitiy... which you indirectly proved by registering a second receiving winow - the first one just stopped receiving because the OS delivers raw input to the application (represented by exactly onw window as the sink).