Firing Mouse Dragged Event

André Geisler eliot at exception-dev.de
Thu May 19 23:28:22 PDT 2011


Hello everybody,

i am really new in XServer programming. At the moment,
i am trying to write my mouse robot.

That's what i have done so far:

#include <stdlib.h>
#include <errno.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <math.h>
#include <stdio.h>
#include <time.h>

#define DEFAULT_XSERVER_ADDR ":0.0"

static Display *display = NULL;
static Window *rootWindow = NULL;

static int robot_state = 0;

int robot_is_inited() {
    return robot_state;
}

void robot_init(const char* xserver) {
    if (!robot_state) {
       if (xserver == NULL) {
          return;
       }
       display = XOpenDisplay(xserver);
       rootWindow = &DefaultRootWindow(display);

       robot_state = 1;
       return;
    }
    return;
    robot_state = 1;
}

void robot_destroy() {
    if (robot_state) {
       XCloseDisplay(display);
    }
    robot_state = 0;
}

void robot_move_mouse(int x, int y) {
    if (robot_state) {
       printf("move to %i,%i\n", x, y);
       XWarpPointer(display, None, *rootWindow, 0, 0, 0, 0, x, y);
       XFlush(display);
    }
}

static void clickMouse_internal(int button) {
    XEvent event;
    if (robot_state) {
       memset(&event, 0x00, sizeof(event));
       event.type = ButtonPress;
       event.xbutton.button = button;
       event.xbutton.same_screen = True;

       XQueryPointer(display, *rootWindow, &event.xbutton.root,
             &event.xbutton.window, &event.xbutton.x_root,
             &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
             &event.xbutton.state);

       event.xbutton.subwindow = event.xbutton.window;
       while (event.xbutton.subwindow) {
          event.xbutton.window = event.xbutton.subwindow;
          XQueryPointer(display, event.xbutton.window, &event.xbutton.root,
                &event.xbutton.subwindow, &event.xbutton.x_root,
                &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
                &event.xbutton.state);
       }

       if (XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) {
       } else {
          XFlush(display);
       }
    }
}

static void releaseMouse_internal(int button) {
    XEvent event;
    if (robot_state) {
       memset(&event, 0x00, sizeof(event));
       event.type = ButtonRelease;
       event.xbutton.button = button;
       event.xbutton.same_screen = True;

       XQueryPointer(display, *rootWindow, &event.xbutton.root,
             &event.xbutton.window, &event.xbutton.x_root,
             &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
             &event.xbutton.state);

       event.xbutton.subwindow = event.xbutton.window;
       while (event.xbutton.subwindow) {
          event.xbutton.window = event.xbutton.subwindow;
          XQueryPointer(display, event.xbutton.window, &event.xbutton.root,
                &event.xbutton.subwindow, &event.xbutton.x_root,
                &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
                &event.xbutton.state);
       }
       if (XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) {
       } else {
          XFlush(display);
       }
    }
}

void robot_release_mouse_button1() {
    releaseMouse_internal(Button1);
}

void robot_press_mouse_button1() {
    clickMouse_internal(Button1);
}

void testRobot() {
    int x = 400;
    int y = 300;
    robot_init(DEFAULT_XSERVER_ADDR);
    if (robot_is_inited()) {
       sleep(1);
       robot_move_mouse(x, y);
       robot_press_mouse_button1();
       sleep(1);
       robot_move_mouse(x + 10, y + 10);
       sleep(1);
       robot_move_mouse(x + 50, y + 50);
       sleep(1);

       //      for (int i = 0; i < 50; i+=2) {
       //         robot_move_mouse(x + i, y + i);
       //         usleep(10000);
       //      }
       robot_release_mouse_button1();
       robot_destroy();
    } else {
       printf("robot not initiated");
    }
}

int main() {

    testRobot();
    return 0;
}

But there is something wrong: When i move the pointer to 10:10,
fire a mouse pressed event, move the pointer afterwards to 50:50
and fire mouse relased event, it should be a mouse dragged event.
On Gnome desktop, everything is fine. Icons, which are in the rectangle,
get marked.
If the unterlying window is for example Gimp, there should be a
line drawed from 10:10 to 50:50. But the line is not drawed.
Instead, only the first dot is drawed at 10:10.

How do i implement a correct mouse dragged event, so it also
works with painting applications such as Gimp?

With kind regards
André Geisler


More information about the xorg-devel mailing list