Utilisation de DBus pour contrôler les applications KDE
A partir de la version 4, les appels dcop ont été remplacés par des appels dbus. L'utilisation d'appels dbus standardise le scripting sous KDE4 mais demande la migration des scripts utilisant dcop vers dbus.
Contents
1. Vocabulaire
DBUS est un concept objet dont mécanisme d'échange est basé sur des IPCs.
Service: un service est un programme qui répond au requêtes des clients. Les services sont indentifiés par un bus qu'on utilise pour identifier les services et émmettre des requêtes. Le nom d'un bus ressemble généralement org.toto.tata. Un programme peut proposer plusieurs bus, mais le nom bus doit être unique.
Objet: un objet est une façon d'organiser de diffèrentes entités. Chaque objet est indentifié par un chemin unique, qui ressemble à org/toto/tata/objet1. Chaque requête envoyée un service doit être effectuée vers un objet spécifique. Les services propsent généralement des objets dont les chemins sont standardisés afin de initier les requêtes simplement.
Interface: chaque requête appartient à une interface, c'est une façon logique de séparer des fonctionnalités différentes. Le nom des interfaces sont indentiques au noms des bus, cependant sans relation commune entre eux.
Méthode ou propriété: est une requête d'opération ou une demande d'information effectuée par client vers le service. Les appels de méthodes sont définies par les interfaces et sont transmis à un objet du service.
- Signal: les signaux sont des messages émis par un service vers les clients en écoute.
2. Outils
- Plusieurs outils sont disponibles:
- qdbus : permet de lister ou d'effectuer des appels((équivalent de dcop)
- qdbusviewer : est une application QT permettant de lister ou d'effectuer des appels dbus rapidement (équivalent de kdcop).
dbus-send : permet également d'effectuer des appels DBUS. Cette outil, fourni par le package dbus sous debian permet d'envoyer des signaux en plus de la possibilité d'effectuer des appels. Il permet, également, de typer les paramètres, d'attendre la réponse pendant une durée définie etc. (voir man page et les exemples ci-dessous)
- D-feet : tout comme qdbusviewer, il permet de lister les appels dbus disponibles et d'effectuer ces appels avec des paramètres au format python.
3. Connexion
Avant de pourvoir effectuer des appels, il faudra se connecter au bus. La connexion se fait en indiquant l'ID du bus dans la variable d'environnement DBUS_SESSION_BUS_ADDRESS. Pour une session KDE, cette variable est initialisée lors du démarrage de la session.
4. Récupération de l'ID
En cas de sessions multiples (connexion physique et une connexion par nxclient, il est possible de lister tous les IDs du bus.
4.1. Méthode 1
- Cette méthode est la plus simple, mais elle risque de lister les ID obsolètes. La récupération se par
egrep '^DBUS_SESSION_BUS_ADDRESS=' ~/.dbus/session-bus/*
4.2. Méthode 2
- Bien qu'elle soit un peu plus complexe, cette méthode permet de lister uniquement les ID des sessions DBUS actives.
for PID in $(pgrep -u $USER startkde) ; do cat /proc/$PID/environ | tr '\0' '\n' | egrep '^DBUS_SESSION_BUS_ADDRESS=' done
Explications
Une session DBUS est lancée pour chaque session de KDE. Le démarrage de KDE se fait par le shell startkde. L'ID bus est donc présent dans les variables environnement de ce shell. Tout l'environnement des programmes en cours d'exécution sont disponibles dans /proc/PID/environ.
5. Appels
- Sous dbus, il existe 2 type d'appels : des méthodes et des propriétés.
5.1. Appels de méthodes
- La syntaxe de l'appel des méthodes est simple : il suffit d'effectuer l'appel directement.
5.1.1. Exemples
5.1.1.1. qdbus
Voici quelques exemples d'appel dbus avec qdbus
Lancer l'économiseur de l'écran en mode verrouillage : qdbus org.kde.screensaver /ScreenSaver org.freedesktop.ScreenSaver.Lock
Activer l'écran de veille : qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive
Basculer l'affichage vers le bureau virtuel suivant: qdbus org.kde.kwin /KWin org.kde.kwin.nextDesktop
Basculer vers le bureau virtuel 1: qdbus org.kde.kwin /KWin org.kde.KWin.setCurrentDesktop 1
- Locker toutes les sessions de l'utilisateur:
for PID in $(pgrep -u $USER startkde) ; do ID="$(cat /proc/$PID/environ | tr '\0' '\n' |awk -FDBUS_SESSION_BUS_ADDRESS= '/DBUS_SESSION_BUS_ADDRESS=/ {print $2}')" DBUS_SESSION_BUS_ADDRESS="$ID" qdbus org.kde.screensaver /ScreenSaver org.freedesktop.ScreenSaver.Lock done
5.1.1.2. dbus-send
Les mêmes exemples d'appels avec dbus-send:
Lancer l'économiseur de l'écran en mode verrouillage : dbus-send --type=method_call --dest=org.kde.screensaver /ScreenSaver org.freedesktop.ScreenSaver.Lock
Noter l'utilisation de l'option type=method_call permet d'indiquer que c'est un appel de méthode (par défaut, dbus-send envoie des signaux)
Activer l'écran de veille : dbus-send --type=method_call --dest=org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive boolean:true
Noter l'utilisation du boolean true en paramètre de la fonction!
Basculer l'affichage vers le bureau virtuel suivant: dbus-send --type=method_call --dest=org.kde.kwin /KWin org.kde.KWin.nextDesktop
Basculer vers le bureau virtuel 1: dbus-send --print-reply --type=method_call --dest=org.kde.kwin /KWin org.kde.KWin.setCurrentDesktop int32:1
Sauvegarder la session en cours de KDE : dbus-send --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.saveCurrentSession
- Locker toutes les sessions de l'utilisateur:
for PID in $(pgrep -u $USER startkde) ; do ID="$(cat /proc/$PID/environ | tr '\0' '\n' |awk -FDBUS_SESSION_BUS_ADDRESS= '/DBUS_SESSION_BUS_ADDRESS=/ {print $2}')" DBUS_SESSION_BUS_ADDRESS="$ID" dbus-send --print-reply --type=method_call --dest=org.kde.screensaver /ScreenSaver org.freedesktop.ScreenSaver.Lock done
5.2. Appels des propriétés
5.2.1. qdbus
- L'appel d'une proprité avec qdbus utilise la syntaxe suivante:
qdbus Nom_Du_Bus Objet org.freedesktop.DBus.Properties.Get Interface Membre
Nom du bus : est une chaîne unique. Par exemple, org.kde.screenSaver ou org.kde.konqueror-PID (PID étant le PID du process).
Objet : est l'objet est le chemin vers l'interface. Par exemple /konqueror/MainWindow_1 ou /ScreenSaver
Interface : est la chaîne représentant la propriété de l'objet jusqu'au dernier point.
Methode : est la chaîne représentant la propriété de l'objet à partir du dernier point
5.2.1.1. Exemples
Nom du profile en cours d'utilisation sous konqueror: qdbus org.kde.konqueror-PID /konqueror/MainWindow_1 org.freedesktop.DBus.Properties.Get org.kde.konqueror.KonqMainWindow currentProfile
- org.kde.konqueror-PID : est le nom du bus (PID étant le PID processus konqueror)
- /konqueror/MainWindow_1 : est le nom de l'objet
org.kde.konqueror.KonqMainWindow : est la chaîne représentant la propriété de l'objet jusqu'au dernier point(Interface).
currentProfile : est la chaîne représentant la propriété de l'objet à partir du dernier point(Membre)!
5.2.2. dbus-send
- L'appel d'une proprité avec dbus-send utilise la syntaxe suivante:
dbus-send --print-reply --type=method_call --dest=Nom_Du_Bus Objet org.freedesktop.DBus.Properties.Get string:Interface string:Membre
Nom du bus : est une chaîne unique. Par exemple, org.kde.screenSaver ou org.kde.konqueror-PID (PID étant le PID du process).
Objet : est l'objet est le chemin vers l'interface. Par exemple /konqueror/MainWindow_1 ou /ScreenSaver
Interface : est la chaîne représentant la propriété de l'objet jusqu'au dernier point.
Methode : est la chaîne représentant la propriété de l'objet à partir du dernier point
5.2.2.1. Exemples
Nom du profile en cours d'utilisation sous konqueror: dbus-send --print-reply --type=method_call --dest=org.kde.konqueror-PID /konqueror/MainWindow_1 org.freedesktop.DBus.Properties.Get __string__:org.kde.konqueror.KonqMainWindow __string__:currentProfile
- org.kde.konqueror-PID : est le nom du bus (PID étant le PID processus konqueror)
- /konqueror/MainWindow_1 : est le nom de l'objet
org.kde.konqueror.KonqMainWindow : est la chaîne représentant la propriété de l'objet jusqu'au dernier point(Interface).
currentProfile : est la chaîne représentant la propriété de l'objet à partir du dernier point(Membre)!
L'utilisation de dbus-send est plus claire dans cet exemple. En effet, l'appel d'une propriété se fait en passant des paramètres à la méthode org.freedesktop.DBus.Properties.Get