2010-04-09 35 views
8

Necesito capturar la pantalla (como pantalla de impresión) para poder acceder a los datos de color de píxeles, para hacer un reconocimiento de imagen, después de eso tendré que generar eventos de mouse en la pantalla, como hacer clic izquierdo, arrastrar y soltar (mover el mouse mientras se presiona el botón, y luego soltarlo). Una vez hecho, la imagen será eliminada.Linux, cómo capturar pantalla y simular movimientos del mouse

Nota: necesito para capturar toda la pantalla todo lo que el usuario puede ver, y necesito para simular clics fuera de la ventana de mi programa (si hace alguna diferencia)

Spec: Linux Ubuntu Idioma: C++

El rendimiento no es muy importante, la función "imprimir pantalla" se ejecutará una vez cada ~ 10 segundos. La duración del proceso puede ser de hasta 24 horas, por lo que el método debe ser estable y la memoria tiene fugas (como de costumbre :)

Pude hacerlo en Windows con Win GDI y algunos eventos de Windows, pero yo no idea de cómo hacerlo en Linux.

Muchas gracias

+1

Esto probablemente tenga algo que ver con el servidor X. (X11) – ereOn

Respuesta

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

construirlo y luego para simular un clic en x, y hacer:

$ ./a.out x y 

es decir

$ g ++ -lX11 sgmousesim2.cpp

$ ./ a.out 123 13

Por si acaso todavía está interesado.

+0

¿Podría explicar esta línea 'mouseClick (Button1);'? ¿Qué es Button1? Soy un desarrollador de Java y no puedo entenderlo. –

1

Swinput es una solución para la simulación de eventos clave/ratón. Necesitas compilarlo probablemente para tu kernel. Xorg proporcionó algunos encabezados para registrar eventos de mouse/clave, pero creo que está roto en este momento. Existe un código Cevtest que se puede utilizar para capturar eventos de los archivos /dev/input/eventX, /dev/input/mice. Puede ser útil.

Editar:

El bug was fixed en una extensión del registro Xorg, por lo que puede estar trabajando demasiado.

Cuestiones relacionadas