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
Collecting the Data for a Partiulcar Process from Pmu for Every 1 Milli Second
Permission Denied in a Folder for a User After Chown and Chmod
Redirect Two or More Stdout to a Single Stdin
Bash Script Variable Scope Issue
Getting Github Files (And Updates) Onto an Ubuntu Web Server
Yocto Build for a Static Library Fails with Error "No Match Found"
Linux - List of Registered Devices
How to Save the Execution Log When We Run a Command Using Putty/Plink
How to Display the Output of a Linux Command on Stdout and Also Pipe It to Another Command
Qmake .Pro File Not Parsed Correctly to Generate Ld_Library_Path
Why Does Unitywebrequest Return Unkown Error When I Do a Get Request on Linux
Suppress or Prevent Duplicate Inotifywait Events
How to Disassemble a System Call
Bash: How to Pass in Arguments to an Alias: Cannot Use a Function - Syntax of Bash Conditionals