internal override void SetCursorPos(IntPtr handle, int x, int y) {
if (handle == IntPtr.Zero) {
lock (XlibLock) {
IntPtr root, child;
int root_x, root_y, child_x, child_y, mask;
/* we need to do a
* QueryPointer before warping
* because if the warp is on
* the RootWindow, the x/y are
* relative to the current
* mouse position
*/
QueryPointer (DisplayHandle, RootWindow,
out root,
out child,
out root_x, out root_y,
out child_x, out child_y,
out mask);
XWarpPointer(DisplayHandle, IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, x - root_x, y - root_y);
XFlush (DisplayHandle);
/* then we need to a
* QueryPointer after warping
* to manually generate a
* motion event for the window
* we move into.
*/
QueryPointer (DisplayHandle, RootWindow,
out root,
out child,
out root_x, out root_y,
out child_x, out child_y,
out mask);
Hwnd child_hwnd = Hwnd.ObjectFromHandle(child);
if (child_hwnd == null) {
return;
}
XEvent xevent = new XEvent ();
xevent.type = XEventName.MotionNotify;
xevent.MotionEvent.display = DisplayHandle;
xevent.MotionEvent.window = child_hwnd.client_window;
xevent.MotionEvent.root = RootWindow;
xevent.MotionEvent.x = child_x;
xevent.MotionEvent.y = child_y;
xevent.MotionEvent.x_root = root_x;
xevent.MotionEvent.y_root = root_y;
xevent.MotionEvent.state = mask;
child_hwnd.Queue.EnqueueLocked (xevent);
}
} else {
Hwnd hwnd;
hwnd = Hwnd.ObjectFromHandle(handle);
lock (XlibLock) {
XWarpPointer(DisplayHandle, IntPtr.Zero, hwnd.client_window, 0, 0, 0, 0, x, y);
}
}
}