Python simulation of mouse and keyboard action

  • 2020-04-02 13:20:53
  • OfStack

I tried to develop a fun project last month, but I didn't have the time. This is part of the project,

This part of the basic communication and so on. First simulate the mouse and keyboard press release action, I use X11

This library, so learn about X11 programming; Secondly, it can be realized by itself using c or c++, but I am py

So I'm going to implement the python module, ctypes for this article, later on

Attached is the python c extension module.

1. The X11 programming

      First of all, a brief introduction of X11 bar, there is an online introduction, I will not repeat. We know that X is server and client

If we want to use its functionality, we need to communicate with the server. use

Display *XOpenDisplay(char *display_name) get a handle pointer to the Display type.

Display_name can be the DISPLAY environment variable, and the output with echo $DISPLAY is :0

A). If the display_name is NULL, the interface defaults to the value held by the environment variable. X11 programming USES several headers

File:

  # include < X11 / Xlib. H >
  # include < X11 / Xutil. H >
  # include < X11 / Xos. H >

I use #include < X11 / Xlib. H > And # include < X11 / extensions/XTest. H > .

Xtest.h has the interfaces XTestFakeButtonEvent, XTestFakeMotionEvent, and XTestFakeButtonEvent that we need to simulate the mouse and keyboard

XTestFakeKeyEvent. For more information, just add the function name of man to the terminal.

For example, the XTestFakeMotionEvent interface:


int XTestFakeMotionEvent(display, screen_number, x, y,delay);
Display *display;  //This value is obtained from XOpenDisplay
int screen_number; //Make it -1 to represent the current screen
int x, y;          //The screen position
unsigned long delay; //Delay for milliseconds and let it be CurrentTime to indicate no delay

Finally, we'll close the Display handle: XCloseDisplay(Display * Display).

Interface implementation is as follows:


#include <stdio.h>
#include <X11/extensions/XTest.h>
#include <X11/Xlib.h>
Display *dspopen(){   

    Display *dsp = XOpenDisplay(NULL);
    if(!dsp) {
        printf("open display failedn");
        return NULL;
    }
    return dsp;
}
int presskey(Display *dsp,int s){  //The keyboard
    if(dsp==NULL)
        return -1;
//    KeySym keysym=XStringToKeysym(s);
    KeyCode key=XKeysymToKeycode(dsp,s);
    if(key==NoSymbol)
        return -1;
    XTestFakeKeyEvent(dsp,key,1,CurrentTime);
    XFlush(dsp);
    return 0;
}
int move(Display *dsp,int x,int y) //The mouse moves
{
    if(0==XTestFakeMotionEvent(dsp,-1,x,y,CurrentTime))
    {
        printf("Cannot move!n");
        return -1;
    }
    return 0;
}
int buttonpress(Display *dsp,int type) //Mouse press, type=1 means left key, 3 means right key, 2 means middle key
{
    if(0==XTestFakeButtonEvent(dsp,type,1,CurrentTime))
    {
        printf("press failedn");
        return -1;
    }
    return 0;
}
int buttonrelease(Display *dsp,int type) //Release the mouse
{
    if(0==XTestFakeButtonEvent(dsp,type,0,CurrentTime))
    {
        printf("release failedn");
        return -1;
    }
    return 0;
}
int releasekey(Display *dsp,int s){ //Keyboard release
    if(dsp==NULL)
        return -1;
//    KeySym keysym=XStringToKeysym(s);
    KeyCode key=XKeysymToKeycode(dsp,s);
    if(key==NoSymbol)
        return -1;
    XTestFakeKeyEvent(dsp,key,0,CurrentTime);
    XFlush(dsp);
    return 0;
}
void dspclose( Display *dsp ){
    if(dsp!=NULL){
        XCloseDisplay(dsp);

    }
}
//int main(){     // The test will be output in front of the cursor at the end of the program c
//    Display *dsp=dspopen();
//    presskey(dsp,'c');
//    releasekey(dsp,'c');
//    dspclose(dsp);
//    return 0;
//}

The main function commented out above can be used as a test, so let's save the above code as display.c

Compiling to a Shared library requires the X11 and Xtst libraries.


gcc -fPIC -shared -o libdisplay.so display.c -lX11 -lXtst

Libdisplay.so is generated when compiled. Now our ctypes module USES this dynamic Shared library.

        2. Brief introduction and use of ctypes

      We know that the types in python are not the same as the types in c, so we should say that there are none, so let's take int,

Python also treats it as a PyObject type. So we need to use the interface provided by ctype to do the type

Conversion. See: http://docs.python.org/2/library/ctypes.html#fundamental-data-types

This link has a diagram showing the interface for the type conversion in detail. Let's show you how to do this.

We load the database through CDLL () interface:


lc=CDLL("./libdisplay.so")

Then you can use the interface provided in the library, but the return value of the dspopen() interface above is a pointer to Display type,

So we need to use c_void_p() to convert:


d=c_void_p(lc.dspopen())

Then d can be used for processing, the code is as follows:


from ctypes import *
import time
class MOUSE:
    LEFT=1
    MiDDLE=2
    RIGHT=3
lc=CDLL("./libdisplay.so")
d=c_void_p(lc.dspopen())
time.sleep(5);
lc.buttonpress(d,c_int(MOUSE.RIGHT))
lc.buttonrelease(d,c_int(MOUSE.RIGHT))
lc.dspclose(d)

The code above opens the right-click menu at the mouse pointer after 5 seconds.

So much for libraries written in c that utilize ctypes. I will write part of the c code as a python c extension and share it later.

Use the interface above to simulate the keyboard and mouse to do some interesting things...


Related articles: