Gext: python xlib

jueves, 26 de noviembre de 2009
Nĭmen hăo!

Para llevar a cabo lo descrito en el post anterior, he pensado en utilizar la implementación de Xlib en Python, llamada python-xlib. Aunque no tiene un desarrollo continuado, creo que me servirá para lo que quiero hacer. El hecho de que esté escrita íntegramente en Python me supone una ventaja, para cotillear su código ;) Además, tiene también varias extensiones portadas. En concreto, la que me interesa es XTEST, que tiene algunos mecanismos para manipular la entrada.

Vamos a hacer algunas pruebas. Para seguirme, tendrás que tener instalado el paquete python-xlib. Esto depende de tu distribución. Por ejemplo, para Debian (y derivados como Ubuntu), el paquete está en los repositorios oficiales, con lo que un simple
# apt-get install python-xlib
lo soluciona.
Empecemos por lo fácil, vamos a intentar mover el ratón... sin tocarlo :D . Abre una consola Python (a mi me gusta ipython), o escríbelo en un fichero y lo ejecutas, como quieras. Primero pongo el código, y luego vemos que hace.

from Xlib.display import Display

d = Display()
r = d.screen().root
for i in range(200):
    r.warp_pointer(i, i)
    d.sync()

Sencillo, ¿verdad? Desgranemoslo. En primer lugar, importar la clase Display. Un display para Xlib es una estación de trabajo, es decir, un monitor, un teclado y un ratón (esto es muy simplista, porque puede haber muchas combinaciones diferentes, por ejemplo, dos o más monitores, o una tableta digitalizadora, etc.). Tenemos en cuenta que X es un servidor, y nosotros actuamos como clientes. Al crear un objeto Display, realmente lo que hacemos es conectarnos al servidor.

De este servidor, obtenemos el screen, un objeto complejo del que nos interesa principamente la ventana raíz, root. A esta ventana le podemos decir que mueva el ratón, con warp_pointer(). Hasta que no hacemos un sync() en el Display, no se envían las acciones al servidor, y por tanto es como si no hiciéramos nada. Para mejorar el efecto, en vez de movernos a un punto, lo que hacemos es desplazarnos por una recta. Para eso es el bucle.

Si lo ejecutas, deberías ver que el ratón se mueve a la esquina superior izquierda (el punto (0,0) de la ventana raíz), y se desplaza 200 píxels en los ejes x e y, con pasos de 1 pixel.

Hacer click es un poco más complejo. Para ello, necesitamos la extensión XTEST. Usaremos una función llamada fake_input(), que simula la pulsación de una tecla, tanto del ratón como del teclado. Veamos el código para pulsar el botón derecho del ratón:

from Xlib.ext import xtest
from Xlib import X

xtest.fake_input(d, X.ButtonPress, 3)
xtest.fake_input(d, X.ButtonRelease, 3)
d.sync()

Importamos los módulos correspondientes: xtest y X (para los eventos que generaremos). Como veis, se usa el mismo display, 'd', que habíamos creado antes (la misma conexión). Le indicamos qué evento queremos que mande al servidor, en este caso primero un ButtonPress y luego un ButtonRelease, y los datos relacionados con el evento, que aquí es el número del botón que queremos pulsar. Al hacer de nuevo un sync(), lo envía todo al servidor X, y dependiendo de donde esté el puntero del ratón, deberíamos ver un menú contextual, o algo así :D

¿Queréis probar el teclado? Bueno, pues eso creo que será en otro post, porque es un poco lioso :P .

Zàijiàn!

0 comentarios:

Publicar un comentario