Capturing Display/Monitor Images, Sending Keyboard Input on Linux

Capturing Display / Monitor Images, Sending Keyboard Input on Linux

I finally have a solution. I believe UrT loads OpenGL on its own so that things such as wallhacks, etc are not possible. Then the best remaining option is taking X screenshots. This worked quite fast, even from a scripting language like Python. The following code takes successive screenshots and displays them as an animation through OpenCV. You need to start UrT in minimized mode of course. The rest of the details are in my project.

import gtk.gdk
import PIL
from opencv.cv import *
from opencv.highgui import *
from opencv.adaptors import PIL2Ipl

w = gtk.gdk.get_default_root_window()
sz = w.get_size()
print "The size of the window is %d x %d" % sz

size_x = 600
size_y = 400
start_x = 0
start_y = 100
end_x = start_x+size_x
end_y = start_y+size_y
box = (start_x, start_y, start_x+size_x, start_y+size_y)

while True:
pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1])
pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1])
width,height = pb.get_width(),pb.get_height()
im = PIL.Image.fromstring("RGB",(width,height),pb.get_pixels())
im = im.crop(box)
cv_img = PIL2Ipl(im)
cvNamedWindow("fps")
cvShowImage("fps", cv_img)
cvWaitKey(30)

Also, for sending keys to the game, the method above did not work, I had to use xdotool in order to send forward walk key to UrT,

xdotool search --name ioUrbanTerror  windowactivate keydown W

Virtual Keyboard (Linux/libevdev) - sending event

I solved this problem. Screen wasn't connect to BeagleBone/Raspberry and system was can't send character to screen.

Generating key press in browser in C

You can do this with the XTest extesion, a simple example:

#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/extensions/XTest.h>
#include <unistd.h>

static void SendKey (Display *disp, KeySym keysym)
{
KeyCode keycode = 0;

keycode = XKeysymToKeycode (disp, keysym);
if (keycode == 0) return;

XTestGrabControl (disp, True);

XTestFakeKeyEvent (disp, keycode, True, 0);
XTestFakeKeyEvent (disp, keycode, False, 0);

XSync (disp, False);
XTestGrabControl (disp, False);
}

/* Main Function */
int main ()
{
Display *disp = XOpenDisplay (NULL);

/* A, B */
SendKey (disp, XK_A);
SendKey (disp, XK_B);

return 0;
}

(adapted from this link)

C++ list screens to display images in the second monitor

It's likely that you need to query Xinerama, which is probably stitching your displays together.

This answer worked for me. I compiled their sample with:

g++ xinerama.c `pkg-config --cflags --libs x11 xinerama` -o test

Linux, how to capture screen, and simulate mouse movements

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

Build it and then to simulate a click at x ,y do:

$ ./a.out x y

i.e.

$ g++ -lX11 sgmousesim2.cpp

$ ./a.out 123 13

Just in case you are still interested.



Related Topics



Leave a reply



Submit