2010-04-09 6 views
8

Ich muss Bildschirm (als Druckbildschirm) in der Art und Weise erfassen, damit ich Pixelfarbdaten zugreifen kann, um einige Bilderkennung zu tun, danach muss ich Mausereignisse generieren auf dem Bildschirm wie Linksklick, Drag & Drop (Maus bei gedrückter Taste bewegen, und dann loslassen). Sobald es fertig ist, wird das Bild gelöscht.Linux, wie Bildschirm zu erfassen und Mausbewegungen zu simulieren

Hinweis: Ich brauche ganzen Bildschirm alles zu erfassen, die Nutzer sehen können, und ich brauche Klicks außerhalb Fenster meines Programms zu simulieren (wenn es einen Unterschied macht)

Spec: Linux ubuntu Sprache: C++

Die Leistung ist nicht sehr wichtig, die "Druckbildschirm" -Funktion wird alle 10 Sekunden ausgeführt. Dauer des Prozesses kann bis zu 24 Stunden dauern, Methode muss stabil sein und Speicherlecks frei (wie üblich :)

Ich konnte in Windows mit Win GDI und einige Windows-Ereignisse tun, aber ich habe keine Idee, wie man es in Linux macht.

Vielen Dank

+1

Das hat wahrscheinlich etwas mit dem X-Server zu tun. (X11) – ereOn

Antwort

13
//sg 

//Solution using Xlib for those who use Linux 
#include <X11/Xlib.h> 
#include<stdio.h> 
#include<unistd.h> 
#include <stdlib.h> 
#include <string.h> 

#include <unistd.h> 

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

void mouseClick(int button) 
{ 
    Display *display = XOpenDisplay(NULL); 

    XEvent event; 

    if(display == NULL) 
    { 
     fprintf(stderr, "Cannot initialize the display\n"); 
     exit(EXIT_FAILURE); 
    } 

    memset(&event, 0x00, sizeof(event)); 

    event.type = ButtonPress; 
    event.xbutton.button = button; 
    event.xbutton.same_screen = True; 

    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &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) fprintf(stderr, "Error\n"); 

    XFlush(display); 

    usleep(100000); 

    event.type = ButtonRelease; 
    event.xbutton.state = 0x100; 

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n"); 

    XFlush(display); 

    XCloseDisplay(display); 
} 
int main(int argc,char * argv[]) { 

    int x , y; 
    x=atoi(argv[1]); 
    y=atoi(argv[2]); 
    Display *display = XOpenDisplay(0); 

    Window root = DefaultRootWindow(display); 
    XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); 
    mouseClick(Button1); 
    XFlush(display); 
    XCloseDisplay(display); 
    return 0; 
} 

es bauen und dann ein Klick auf x zu simulieren, y tun:

$ ./a.out x y 

dh

$ g ++ -lX11 sgmousesim2.cpp

$ ./ a.out 123 13

Nur für den Fall, dass Sie noch interessiert sind.

+0

Können Sie diese Zeile 'mouseClick (Button1) erklären;'? Was ist Button1? Ich bin ein Java-Entwickler und kann es nicht verstehen. –

1

Swinput ist eine Lösung, Maus/Schlüsselereignisse für die Simulation. Sie müssen es wahrscheinlich für Ihren Kernel kompilieren. Xorg hat einige Header für die Aufzeichnung von Maus-/Schlüsselereignissen bereitgestellt, aber ich denke, es ist im Moment kaputt. Es gibt einen C Code evtest, der verwendet werden kann, um Ereignisse von /dev/input/eventX, /dev/input/mice Dateien zu erfassen. Es kann hilfreich sein.

Edit:

Die bug was fixed in Xorg Satzerweiterung, so kann es auch funktionieren.