c++ X11 global change cursor shape - c++

I'm writing a mouse emulation program for Linux based on input from external hardware (Leap Motion Controller). For proper operation, I want to change the shape of the cursor to convey status information to the user related to their operation of the cursor. I'm currently writing a user space program to handle this. Mouse movement and mouse clicks are handled using the XTest library, but right now I can't find a way to change the shape of the cursor.
Using XDefineCursor() I've been able to change the cursor to a custom shape on a window owned by my program, but I need it in the full graphical environment, since this program will remain
hidden in the background most of the time.
I'd also prefer to not write a device driver and stay in user space for now if possible. Also I'd prefer to not have to change the code for the Display manager (ie Unity or LXDE).
Edit:
The hardware is the Leap Motion Controller. I need to display to the user if they are still in the sensor's range, or outside the range.

You can watch for cursor changes with XFixes protocol and then modify cursor each time it is changed adding your graphics to whatever window tried to set it ( SelectCursorInput/GetCursorImage/CursorNotify event)

Related

Getting mouse movement input rather than the cursor position (C++)

I want to have my code read the movement of the mouse and act accordingly, for example, if you are moving your mouse up, you print the mouse is moving up in the console and sort of like that. (I am using Windows 10.)
The problem is, I could find a lot of articles that take the coordinates of the mouse cursor, but couldn't find one that deals with the real raw mouse input. The reason I want to do it this way is that when your cursor hits the border and cannot go further, the cursor position wouldn't change and the program won't recognize the mouse movement even though the mouse is "physically" moving. Another problem is that certain programs can "lock" your cursor to stay in a fixed position. For example, most FPS games do that.
Therefore, I wanted to get the raw input that the sensor of the mouse gives to the computer and utilize them instead of cursor position.
Therefore, I wanted to get the raw input that the sensor of the mouse gives to the computer and utilize them instead of cursor position.
Use the Raw Input API for that. Call RegisterRawInputDevices() to register the target mouse device(s) you want to monitor (there could be multiple connected to the PC), and then handle WM_INPUT messages containing the raw input data from the mouse(s).

Simulate mouse click without moving the cursor

I wrote an application that detects all active Windows and puts them into a list.
Is there a way to simulate a mouseclick on a spot on the screen relative to the Windows location without actually moving the cursor?
I don't have access to the buttons handle that is supposed to be clicked, only to the handle of the window
Is there a way to simulate a mouseclick on a spot on the screen relative to the Windows location without actually moving the cursor?
To answer your specific question - NO. Mouse clicks can only be directed where the mouse cursor actually resides at the time of the click. The correct way to simulate mouse input is to use SendInput() (or mouse_event() on older systems). But those functions inject simulated events into the same input queue that the actual mouse driver posts to, so they will have a physical effect on the mouse cursor - ie move it around the screen, etc.
How do I simulate input without SendInput?
SendInput operates at the bottom level of the input stack. It is just a backdoor into the same input mechanism that the keyboard and mouse drivers use to tell the window manager that the user has generated input. The SendInput function doesn't know what will happen to the input. That is handled by much higher levels of the window manager, like the components which hit-test mouse input to see which window the message should initially be delivered to.
When something gets added to a queue, it takes time for it to come out the front of the queue
When you call Send­Input, you're putting input packets into the system hardware input queue. (Note: Not the official term. That's just what I'm calling it today.) This is the same input queue that the hardware device driver stack uses when physical devices report events.
The message goes into the hardware input queue, where the Raw Input Thread picks them up. The Raw Input Thread runs at high priority, so it's probably going to pick it up really quickly, but on a multi-core machine, your code can keep running while the second core runs the Raw Input Thread. And the Raw Input thread has some stuff it needs to do once it dequeues the event. If there are low-level input hooks, it has to call each of those hooks to see if any of them want to reject the input. (And those hooks can take who-knows-how-long to decide.) Only after all the low-level hooks sign off on the input is the Raw Input Thread allowed to modify the input state and cause Get­Async­Key­State to report that the key is down.
The only real way to do what you are asking for is to find the HWND of the UI control that is located at the desired screen coordinates. Then you can either:
send WM_LBUTTONDOWN and WM_LBUTTONUP messages directly to it. Or, in the case of a standard Win32 button control, send a single BM_CLICK message instead.
use the AccessibleObjectFromWindow() function of the UI Automation API to access the control's IAccessible interface, and then call its accDoDefaultAction() method, which for a button will click it.
That being said, ...
I don't have access to the buttons handle that is supposed to be clicked.
You can access anything that has an HWND. Have a look at WindowFromPoint(), for instance. You can use it to find the HWND of the button that occupies the desired screen coordinates (with caveats, of course: WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?).

Setting/Getting my absolute mouse position in windowed mode

I searched, but most posts are just telling me what I already have, so below is basically my code right now:
DIKeyboard->Acquire();
DIMouse->Acquire();
DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrState);
DIKeyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)&keyboardState);
MousePos.x += mouseCurrState.lX;
MousePos.y += mouseCurrState.lY;
Any post telling me how to get absolute position just says to use those last two lines. But my program is windowed, and the mouse can start anywhere on the screen.
i.e. If my mouse happens to be in the centre of my screen, that becomes position 0,0. I basically just want the top left of my window (not my screen) to be my 0,0 mouse coordinates, but am having a hard time finding anything relevant.
Thanks for any help! :)
Following the discussion in the comments, you'll have to decide which method works best for you. Unfortunately, having never worked with DirectInput, I do not know the ins-and-outs of it.
However, Window Messages work best for RTS-style controls, where a cursor is drawn to screen. This is due to the fact that this respects user settings, such as mouse acceleration and mouse speed, whereas DirectInput only uses the driver settings (so not the control panel settings). The user will expect the mouse to feel the same, especially in windowed mode.
DirectInput works better for FPS-style controls, when there is no cursor drawn, as window messages give you only the cursor coordinates, and not offset values. This means that once you are at the edge of the screen, window messages will no longer allow you to detect the mouse being moved further (actually, I am not 100% sure on this, so if someone could verify, please feel free to comment).
For keyboard, I would definitely suggest window messages, because DirectInput offers no advantages, and WM input is easier to use, and quite powerful (the WM_KEYDOWN messages contains a lot of useful data), and it'll allow you (via TranslateMessage) to get good text input, adjusted to locale, etc.).
Solving your problem with DirectInput:
You could probably use GetCursorPos followed by ScreenToClient to initialise your MousePos structure. I'm guessing you'll need to redo this every time you lose mouse input and reacquire it.
Hybrid solution (for RTS like controls):
It might be possible to use a hybrid solution for the mouse if you desire RTS-like controls. If this is the case, I suggest, though I have not tested this, to use WM for the movement of the mouse, which avoids the need for workaround mentioned above, and only use DirectInput to detect additional mouse buttons.
Now one thing I think you should do in such a hybrid approach is not directly use the button when you detect it via DirectInput, but rather post a custom application message to your own message queue (using PostMessage and WM_APP) with the relevant information. I suggest this because using WM you do not get the real-time state of the mouse & keyboard, but rather the state at the time of the message. Posting a message that the button was pressed allows you to handle the extra buttons in the same state-dependent manner (I don't know how noticeable this 'lag' effect is). It also makes the entire input handling very uniform, as every bit of input with this enters as a window message.

Raw mouse input with Windows

Reading this article "Taking Advantage of High-Definition Mouse Movement" - http://msdn.microsoft.com/en-us/library/windows/desktop/ee418864(v=vs.100).aspx, I surmise that one should use raw input for more precise readings from input devices.
The article states that WM_MOUSEMOVE's primary disadvantage is that it is limited to the screen resolution.
Upon close inspection of the RAWMOUSE structure I see that lLastX and lLastY are long values and you get the delta via them.
To me it looks like WM_MOUSEMOVE and WM_INPUT is the same except with WM_INPUT you do not get acceleration (pointer ballistics) applied.
Are both WM_MOUSEMOVE and WM_INPUT limited to the screen resolution?
If so, what is the benefit of using WM_INPUT?
RAWMOUSE gives you logical coordinates for the mouse based on the mouse's native resolution.
That is, you see the actual movement of the mouse.
Windows will use the mouse speed and acceleration (ballistics) settings to update the cursor position. Because of course the two are not linked - the apparent movement of the mouse must be interpreted to generate a cursor movement else how can more than one mouse be supported?
If you wish to control a pointer, as far as I can tell there is no reason to duplicate the Windows mouse ballistics calculations. Just let windows do it. Therefore for controlling the pointer, you should just use WM_MOUSEMOVE. That is, unless you wish to disable the mouse acceleration settings in your application.
However, if you want to control the player's POV (point of view), or use the mouse to control an in-game object such as a spaceship flight yoke, then the RAWMOUSE data gives you the best possible access to the movement of the mouse, and you can implement your own algorithm to convert that into flight yoke/POV movement.
The main benefit and reason to use it is that that with rawInput you can use two mouses or more. Presently I write small game prototype which is designed to be played by two players with two mouses/mices - It is more complicated but It works and it is not bad because I do nod need to link external libs.

Qt - Catch events normally handled by the Window Manager

I'm not sure quite how to phrase the question concisely, so if there is a similar question, please point me in the right direction and close this one.
I am currently building a CAD app, the user interacts within the 3D viewports primarily through the mouse and the three keyboard modifiers (alt, shift, ctrl). Shift and control modify the currently selected tool options, and alt operates the camera - much like any other 3D CAD app.
However I'm currently developing with a Gnome desktop, and it's window manager (AFAIK) catches any Alt-RightButton mouse dragging events and interprets them as a window drag command - even when not holding the title bar and regardless of the currently highlighted widget.
This is a disaster for me because camera keyboard controls are quite standardised in my target industry. So does anyone know of a way to override this behaviour, preferably from within Qt, and preferably focus it for my one scenario in one particular widget class?
Thank you,
Cam
If you use the Qt::X11BypassWindowManagerHint on the window, then the window manager can't steal your keypresses. However, this means you lose the native window frame (including decoration, moving, and resizing), so it is likely you don't want to do this.
Another way: if your users are only on 1 or 2 varieties of Linux, add something to the installer which asks the user whether they want to manipulate the gnome (or whatever) keysettings, and if so, changes them via gconftool-2 (or equivalent).