2010-04-09 19 views
8

Je dois capturer l'écran (en tant qu'imprimante) de manière à pouvoir accéder aux données de couleur de pixel, à faire une reconnaissance d'image, après quoi je devrai générer des événements de souris sur l'écran comme le clic gauche, faites glisser et déplacer (déplacer la souris tout en appuyant sur le bouton, puis relâchez-le). Une fois cela fait, l'image sera supprimée.Linux, comment capturer l'écran et simuler les mouvements de la souris

Note: Je dois capturer tout écran tout que l'utilisateur peut voir, et je dois simuler des clics en dehors de la fenêtre de mon programme (si cela fait une différence)

Spec: Linux ubuntu Langue:

C++

Les performances ne sont pas très importantes, la fonction "impression d'écran" sera exécutée toutes les ~ 10 sec. La durée du processus peut aller jusqu'à 24 heures, donc la méthode doit être stable et les fuites de mémoire gratuites (comme d'habitude :)

J'ai été capable de faire dans Windows avec Win GDI et certains événements Windows, mais je ne idée comment le faire sous Linux.

Merci beaucoup

+1

Cela a probablement quelque chose à voir avec le serveur X. (X11) – ereOn

Répondre

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; 
} 

construis, puis de simuler un clic à x, y faire:

$ ./a.out x y 

-à-dire

$ g ++ -lX11 sgmousesim2.cpp

$ ./ a.out 123 13

Juste au cas où vous êtes toujours intéressé.

+0

Pourriez-vous expliquer cette ligne 'mouseClick (Button1);'? Qu'est-ce que Button1? Je suis un développeur Java et je ne peux pas le comprendre. –

1

Swinput est une solution pour simuler la souris/événements clés. Vous devez le compiler probablement pour votre noyau. Xorg a fourni des en-têtes pour l'enregistrement des événements souris/clé mais je pense que c'est cassé pour le moment. Il y a un C code evtest qui peut être utilisé pour capturer des événements de /dev/input/eventX, /dev/input/mice fichiers. Cela peut être utile.

Edit:

Le bug was fixed en extension d'enregistrement Xorg, il peut travailler aussi.