Moving mouse pointer while keeping the button state (C++)

Eugenio Rustico jfrusciante at tiscali.it
Fri Feb 29 11:37:41 PST 2008


  Hello,
I'm writing a linux command line application which should move the
mouse pointer around the screen (in absolute coordinates) and
simulates mouse button clicks, like it was a real user interacting
with several different applications.
  My first trial was to call XWarpPointer; unfortunately, it seems to
forget the mouse button state. E.g.

----
XEvent bevent;
XQueryPointer(display, RootWindow(display, DefaultScreen(display)),
&bevent.xbutton.root, &bevent.xbutton.window, &bevent.xbutton.x_root,
&bevent.xbutton.y_root, &bevent.xbutton.x, &bevent.xbutton.y,
&bevent.xbutton.state);
	bevent.xbutton.subwindow = bevent.xbutton.window;
	while(bevent.xbutton.subwindow)	{
		bevent.xbutton.window = bevent.xbutton.subwindow;
		XQueryPointer(display, bevent.xbutton.window, &bevent.xbutton.root,
&bevent.xbutton.subwindow, &bevent.xbutton.x_root,
&bevent.xbutton.y_root, &bevent.xbutton.x, &bevent.xbutton.y,
&bevent.xbutton.state);
	}
bevent.xbutton.state = (pressed?Button1Mask:0x100);
bevent.xbutton.x = lastx;
bevent.xbutton.y = lasty;
XSendEvent(display, InputFocus, True, 0xfff, &bevent);
XWarpPointer(display, ..., x, y);
...
---
  Now the button state is not anymore "pressed". If I use this code to
draw on Gimp, I draw points and not lines.
  So, I tried to send a mousemotion event; this approach needs
coordinates relative to the window, though I have absolute ones. I'm
sure I can translate them someway, but:

- The real mouse pointer is still: events are simulated correctly, but
the user can't see the mouse moving;

- If I go out from a window and click outside it, the window keeps the
focus and keeps to grab all the events (though I XQuery again),
beacuse the real pointer is not moving and remains on the initial
window (e.g.: if I have two Gimp subwindows, I keep sending the events
on the first though I release the button and move the pointer on the
second);

- If I send the events to the root window, no application receives any
click. I see the pointer moving, but I can't use it.

  The ideal behaviour for me would be like the java.awt.Robot class:
it has three methods setPos(absX,absY), mousePress() and
mouseRelease() which keep the mouse button state while moving from an
application to another; and I see the real cursor moving, exactly as
if it was me physically moving the mouse.

  In the rows, I tried to use SDL, GTK and QT libraries also, but they
seem to have the same problem: if I move the pointer I lose the button
state, or I can't go out from the original window.

  Anyone could suggest me how can I solve these problems? Maybe I can
somehow send all events directly to the screen?
  Thanks.



More information about the xorg mailing list