XServer Programmierung: Mouse Dragged Event auslösen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

XServer Programmierung: Mouse Dragged Event auslösen

Beitrag von eliot » 17.05.2011 13:21:10

Hallo,

ich habe in c unter Nutzung der Xlib einen Mouse Robot programmiert,
der folgende Features Unterstützt:
- Mouse pressed
- Mouse released
- Mouse move

Hier die Sourcen:

Code: Alles auswählen

#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;
}
Und jetzt das Problem: Mouse dragged Events sind nicht korrekt.
Wenn ich den Pointer auf 10:10 setze, danach ein Mouse Pressed Event auslöse
und dann den Pointer auf 20:20 setze, sollte das einem Mouse Dragged Event entsprechen.
Auf dem Gnome Desktop, funktioniert das auch (Es wird das Lasso angezeigt um einen Bereich zu markieren).
Wenn ich allerdings Gimp nutze, wird anstatt einer Linie nur der erste Punkt gezeichnet (auf Position 10:10).

Habt ihr eine Idee was ich falsch mache?

Grüße
eliot

eliot
Beiträge: 258
Registriert: 06.05.2005 18:05:32

Re: XServer Programmierung: Mouse Dragged Event auslösen

Beitrag von eliot » 20.05.2011 07:54:32

Niemand eine Idee?

Antworten