2010-04-09 1 views
8

Мне нужно захватить экран (как экран печати) таким образом, чтобы я мог получать данные о цвете пикселей, чтобы сделать некоторое распознавание изображений, после чего мне нужно будет генерировать события мыши на экране, например, щелчок левой кнопкой мыши, перетаскивание (перемещение мыши при нажатии кнопки, а затем ее отпускание). После его завершения изображение будет удалено.Linux, как захватить экран и имитировать движения мыши

Примечание: мне нужно, чтобы захватить весь экран все, что пользователь может видеть, и мне нужно, чтобы имитировать щелчки за пределами окна моей программы (если это делает никакой разницы)

Spec: Linux Ubuntu Язык:

C++

Производительность не очень важна, функция «экрана печати» будет выполняться через каждые ~ 10 секунд. Продолжительность процесса может составлять до 24 часов, поэтому метод должен быть стабильным, а утечка памяти бесплатна (как обычно:

Я смог сделать в окнах с выигрышем GDI и некоторыми событиями окон, но I'ev no Идея, как это сделать в Linux.

спасибо

+1

Это, вероятно, связано с X-сервером. (X11) – ereOn

ответ

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

Построить его, а затем, чтобы имитировать щелчок в точке х, у делать:

$ ./a.out x y 

т.е.

$ г ++ -lX11 sgmousesim2.cpp

$ ./ a.out 123 13

На всякий случай вы все еще заинтересованы.

+0

Не могли бы вы объяснить эту строку 'mouseClick (Button1);'? Что такое Button1? Я разработчик Java и не могу это понять. –

1

Swinput является решением для имитации мыши/ключевые события. Вам нужно скомпилировать его, вероятно, для вашего ядра. Xorg предоставил некоторые заголовки для записи событий мыши/клавиши, но я думаю, что это нарушено на данный момент. Существует C код evtest, который может быть использован для захвата событий от /dev/input/eventX, /dev/input/mice файлов. Это может быть полезно.

Edit:

bug was fixed в расширении звукозаписывающей Xorg, поэтому он может работать тоже.

Смежные вопросы