View previous topic :: View next topic |
Author |
Message |
TGL Bodhisattva
Joined: 02 Jun 2002 Posts: 1978 Location: Rennes, France
|
Posted: Mon Nov 14, 2005 1:33 am Post subject: [X11] Contrôler X avec l'extension XTest |
|
|
Bon alors, puisqu'on peut se servir de ce forum pour remettre à plat les conclusions de discussions qu'on a trouvées intéressantes, voilà un petit résumé des évènements de ce topic, initié par LostControl qui se demandait comment zoomer sous Xorg, comme avec un Ctrl+Alt+Plus, mais depuis une simple commande, sans clavier.
L'extension XTest
L'extension XTest est une extension X11 qui permet de générer des évenements, comme des pressions de touches du clavier ou des mouvements de souris. C'est vraiment une extension "de base" sous Xorg ou XFree, et il est à peu près certains qu'elle est déjà prête à l'emploi chez vous. Cette commande vous le confirmera : Code: | grep -i xtest /var/log/Xorg.0.log |
Les évenements XTest se distinguent de ceux qu'on utilise habituellement avec la Xlib en ça qu'ils ne sont pas destinés à une fenêtre/application particulière, mais au serveur X lui même. Ce sont donc des évenements de bas niveau, en toute chose similaires à ceux provenant d'un vrai périphérique, et qui suivront les même étapes de traitement ensuite.
Cette différence est importante dans l'exemple qui nous intérresse : si on génère, façon Xlib, un "Ctrl+Alt+Plus" à destination par exemple de la fenêtre qui a le focus, ça ne va provoquer un zoom de X, mais juste une tentative de raccourcis clavier pour l'application concernée.
On peut retrouver une documentation officielle de XTest par exemple ici.
Utiliser XTest en C
La première solution pour cette affaire de zoom de X a été trouvée en quelques lignes de C, inspirées par le programme numlockx, qui se sert lui de XTest pour générer un évenement clavier de "vérouillage du pavé numérique". Voilà donc xzoom.c dans sa version écrite par LostControl : Code: | #include <stdio.h>
#include <string.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#define NBR_KEYS 3
void executeKeys(Display *disp, unsigned int *keys, int length) {
int i;
/* press */
for (i=0; i<length; i++) {
XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keys[i]), True,
CurrentTime);
}
/* release */
for (i=length-1; i>=0; i--) {
XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keys[i]), False,
CurrentTime);
}
}
int main(int argc, char **argv) {
Display* disp = XOpenDisplay(NULL);
unsigned int zoom_in[NBR_KEYS] = {XK_Control_L, XK_Alt_L, XK_KP_Add};
unsigned int zoom_out[NBR_KEYS] = {XK_Control_L, XK_Alt_L, XK_KP_Subtract};
if (disp == NULL) return 1;
if (argc != 2) {
printf("Please specify a parameter: in|out\n");
return 1;
}
if (strcmp(argv[1], "in") == 0) {
executeKeys(disp, zoom_in, NBR_KEYS);
} else if (strcmp(argv[1], "out") == 0) {
executeKeys(disp, zoom_out, NBR_KEYS);
} else {
printf("Unknown parameter. Please specify a parameter: in|out\n");
}
XCloseDisplay(disp);
return 0;
} | Ça se compile comme ça : Code: | % gcc -o xzoom xzoom.c -lX11 -lXtst | ...et ça s'utilise comme ça : (avec "in", on a l'équivalent d'un Ctrl+Alt+Plus, et avec "out", on aurait un Ctrl+Alt+Moins).
Utiliser XTest en Python
Une deuxième solution est d'utiliser le module Python Xlib (dans portage, dev-python/python-xlib). Voilà un petit programme d'exemple, xkeystroke : Code: | #!/usr/bin/python
import sys
from Xlib import display, X, XK
def keystroke(sequence):
global disp, valid_keys
down_keycodes = []
for key in sequence.split('+'):
if key in valid_keys:
keycode = disp.keysym_to_keycode(XK.string_to_keysym(key))
disp.xtest_fake_input(X.KeyPress, keycode)
down_keycodes.append(keycode)
else: print >>sys.stderr, "%s: invalid key name" % key
while down_keycodes:
keycode = down_keycodes.pop()
disp.xtest_fake_input(X.KeyRelease, keycode)
valid_keys = {}
for name in dir(XK):
if name[:3] == 'XK_':
valid_keys[name[3:]] = None
disp = display.Display()
for sequence in sys.argv[1:]:
keystroke(sequence)
disp.sync() | On peut lui demander de simuler n'importe quel séquence de touches clavier : Code: | % ./xkeystroke Shift_L+a b Shift_L+c
AbC | La séquence "AbC" arrive ici jusqu'au xterm depuis lequel on a lancé le programme, parceque le serveur X n'a rien à faire de ces évenements, et donc il transmet au Window Manager, qui n'en a rien à faire non plus, et qui donc les transmet à la fenêtre ayant le focus, ici notre xterm, qui lui enfin les accepte et réagit.
Pour faire un "zoom in", on utiliserait : Code: | % ./xkeystroke Ctrl_L+Alt_L+KP_Add | Notez qu'il faut utiliser des noms de touches valides pour Xorg (pour le "-" du pavé numérique, ça serait "KP_Substract").
Utiliser XTest sans le savoir
Avec un peu de retard (mais c'est tant mieux), on a en fait trouver un programme qui à pour vocation de générer des évennements via l'extension XTest. Il s'agit de x11-misc/xautomation, qui fournie la commande xte. Avec cette commande, notre "zoom in" pourrait s'écrire : Code: | % xte 'keydown Control_L' 'keydown Alt_L' 'key KP_Add' 'keyup Alt_L' 'keyup Control_L' | Oui, c'est un peu long, mais c'est parcequ'on décompose chaque pression puis relâche des touches (sauf pour celle du milieu, 'key KP_Add' étant un raccourcis pour la séquence 'keydown KP_Add' 'keyup KP_Add'). Dans le cas du zoom, on peut bien sûr se faciliter un peu la tâche avec un petit script xzoom.sh qui prendrait juste "in" ou "out" en paramètre, et génèrerait les séquences de touches correspondantes : Code: | #!/bin/bash
prog=$(basename "${0}")
xte=$(which xte 2>/dev/null)
if [[ -z "${xte}" ]] ; then
echo "This scripts requires \"xte\" from \"x11-misc/xautomation\"" >&2
exit 1
fi
mod_down[0]="keydown Control_L"
mod_down[1]="keydown Alt_L"
in[0]="key KP_Add"
out[0]="key KP_Substract"
mod_up[0]="keyup Control_L"
mod_up[1]="keyup Alt_L"
if [[ "${1}" == "in" || "${1}" == "out" ]]; then
eval ${xte} \"\${mod_down[@]}\" \"\${${1}[@]}\" \"\${mod_up[@]}\"
else
echo "Usage: ${prog} <in|out>" >&2
exit 2
fi |
Notez que le programme xte offre vraiment un accès très complet aux fonctionnalités de XTest, et permet aussi de générer par exemple des mouvements du curseur de la souris. Associé à visgrep, une autre commande du même paquet mais non liée à XTest elle et qui permet de trouver l'emplacement d'éléments graphiques à l'écran, on a ainsi une véritable solution pour automatiser des actions sur des GUI sous X. |
|
Back to top |
|
|
Enlight Advocate
Joined: 28 Oct 2004 Posts: 3519 Location: Alsace (France)
|
Posted: Tue Nov 15, 2005 10:31 am Post subject: |
|
|
Ah bah, grande classe les deux!!! |
|
Back to top |
|
|
Dominique_71 Veteran
Joined: 17 Aug 2005 Posts: 1877 Location: Switzerland (Romandie)
|
Posted: Sun Jun 03, 2007 4:29 pm Post subject: |
|
|
Petite question bête et méchante: est-il possible de ne zoomer qu'une fenêtre avec ça? Chaque fois que j'essaie, cela fait la même chose que Ctrl-Alt-+.
Il y a une application qui fait presque cela, façon xmag mais en mieux: xzoom, et ses dépendances sont la glib et X. http://packages.debian.org/unstable/x11/xzoom _________________ "Confirm You are a robot." - the singularity |
|
Back to top |
|
|
lalebarde Guru
Joined: 03 Sep 2006 Posts: 464 Location: France, Haute-Garonne
|
Posted: Sun Oct 28, 2007 5:09 pm Post subject: |
|
|
Mille fois merci TGL ! .
Ca faisait une vingtaine d'heure cumulées que je recherchait ça sur la toile. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|