|
Автор |
Сообщение |
den
Старожил
Зарегистрирован: 31.01.2006 Сообщения: 13870 Откуда: Кировоград, Украина
|
|
|
|
D-Bus — это система межпроцессного взаимодействия, предоставляющая приложениям несколько шин для передачи сообщений. В этой статье мы рассмотрим несколько полезных трюков с D-Bus, которые пригодятся любому пользователю.
Вкратце о D-Bus
Чтобы ты понимал текст статьи, нужно разобраться, как работает D-Bus и что вообще это такое. D-Bus не является чем-то инопланетным и отдельно стоящим. Это часть проекта freedesktop.org. D-Bus интегрируется во многие рабочие среды и доступна для GLib, GCJ (Java), Mono, Qt и Python.
Приложения в рамках одной среды рабочего стола должны тесно взаимодействовать между собой. В KDE не так давно для этого использовалась система DCOP (Desktop COmmunication Protocol), в настоящее время заменена на D-Bus. Но D-Bus - это не единственный возможный вариант. Кроме D-Bus, существовала возможность коммуникации с помощью CORBA, SOAP или XML-RPC. Но CORBA требует много системных ресурсов, а SOAP и XML-RPC предназначены больше для Web-сервисов.
В GNOME раньше использовалась Bonobo (основана на CORBA), но низкая производительность CORBA сказывалась на быстродействии GNOME, да и привязка к GObject никого не радовала (из-за нее Bonobo не использовался в других рабочих средах).
Перед разработчиками рабочих сред стала задача: организовать обмен сообщениями между приложениями двух разных сред. Для решения этой задачи как раз и был создан проект D-Bus. Проект оказался довольно успешным и KDE4 теперь полностью переведен на D-Bus.
Теперь разберемся, как работает D-Bus. D-Bus предоставляет две шины: системную и сессионную. Системная шина создает при запуске демона D-Bus и используется для "общения" различных демонов и практически недоступна для пользовательских приложений. Сессионная шина, наоборот, создается для пользователя, вошедшего в систему - по ней будут "общаться" приложения, с которыми работает пользователь. Для каждой сессионной шины запускается отдельная копия демона.
У каждого сообщения, передаваемого по шине, есть отправитель и получатель. Адреса отправителя и получателя называются путями объектов: D-Bus предполагает, что каждое приложение состоит из набора объектов, а сообщения пересылаются не между приложениями, а между объектами приложений.
У каждого объекта может быть один или более интерфейсов. Интерфейсы представлены в виде именованных групп методов и сигналов - как в интерфейсах Glib, Qt и Java.
D-Bus предусматривает собственную концепцию сервисов. Сервис - это уникальное местоположение приложения на шине. При запуске программа регистрирует один или несколько сервисов на шине, которыми она будет владеть, пока не освободит их. До момента освобождения ни одно другое приложение не сможет занять уже занятый сервис. Сервисы именуются аналогично интерфейсам.
С помощью сервисов можно реализовать автоматический запуск необходимых приложений при поступлении сообщений. Для этого нужно включить автоактивацию и в настройках D-Bus сопоставить с сервисом определенное приложение. Тогда D-Bus запустит приложение при поступлении сообщения на тот или иной сервис.
При завершении программы освобождаются все зарегистрированные при ее запуске сервисы. D-Bus при этом посылает сигнал о том, что сервис закрыт.
Когда приложение подключается к шине, оно должно указать, какие сообщения оно желает получать. Приложение будет получать только те сообщения, которые ему нужно, а проблему фильтрации D-Bus берет на себя.
Сообщения D-Bus делятся на четыре вида: вызовы методов, результаты вызовов, сигналы и ошибки. Сообщения первого вида используются для вызова методов над объектами, подключенными к D-Bus. После этого объект обязан вам возвратить или результат вызова или ошибку в сообщениях соответствующего вида.
В D-Bus у каждого объекта свое уникальное имя. Имя объекта напоминает путь в файловой системе, например, org/kde/kspread/sheets/1/cells/1/1. Обычно путь имеет какую-нибудь смысловую нагрузку. Например, в данном случае, мы обращаемся к ячейке 1:1 на первом листе электронной книги KSpread. Но имена могут быть совершенно бессмысленными, например, /com/appl1/c5444sf956a. Тут все зависит от разработчиков.
D-Bus и скринсейверы
Начнем с самых простых трюков, связанных с D-Bus и скринсейверами. Заблокировать экран можно следующей командой:
Код: |
qdbus org.kde.krunner /ScreenSaver Lock |
Иногда напрягает, что хранитель экрана вообще запускается. Ну не нужен он мне. Конечно, можно в настройках KDE его отключить, но раз сегодня мы говорим о D-Bus, то тебе пригодится следующая команда:
Код: |
qdbus org.kde.krunner /ScreenSaver SimulateUserActivity |
В некоторых случаях X-сервер может вообще потушить экран. Чтобы обойти эту "feature", нужно ввести команду:
Первый 0 - это время в секундах до гашения монитора без выключения монитора, второй 0 - это время до перехода в ждущий режим, а третий - до выключения монитора. Вообще вместо команды xset можно править xorg.conf, но учитывая, что в современных дистрибутивах он вообще отсутствует, то лучше все-таки использовать команду xset.
Вернемся к методу SimulateUserActivity. Метод, как следует из его названия, симулирует активность пользователя. Его нужно вызывать периодически. Но не будешь же ты вводить приведенную выше команду, скажем, каждые 30 секунд? Тогда можно набросать небольшой сценарий:
Код: |
#!/bin/bash
$* &
while jobs | grep -q Running
do
qdbus org.kde.krunner /ScreenSaver SimulateUserActivity
sleep 30
done |
Сценарию нужно передать командную строку. Да, именно командную строку - он запустит приложения, и будет симулировать активность пользователя. Сохрани сценарий как /usr/bin/simulate. После этого установи права доступа:
Код: |
sudo chmod +x /usr/bin/simulate |
После этого запускай сценарий так:
Код: |
$ simulate <команда> |
Например:
Код: |
$ simulate mplayer film.avi |
Вообще, я в курсе, что у MPlayer есть параметр -stop-xscreensave, но у других проигрывателей подобного параметра может и не оказаться.
Сессии и D-Bus
Сохранить текущую сессию можно вот такой командой:
Код: |
dbus-send –dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.saveCurrentSession |
Если ты хочешь сохранить сессию и выйти, то пригодится вот такая команда:
Код: |
/usr/bin/qdbus org.kde.ksmserver /KSMServer logout 0 2 0 |
Цитата: |
Ошибка: dbus: UUID file ‘/var/lib/dbus/machine-id’ contains invalid hex data |
Увидели такое сообщение об ошибке? Исправить ситуацию поможет команда:
Код: |
dbus-uuidgen > /var/lib/dbus/machine-id |
Трюки с буфером обмена
В Windows я использовал довольно неплохой менеджер закачек FlashGet. Он активировался, как только в буфере обмена появится ссылка (URL). Появлялось окно, где нужно было либо подтвердить закачку, либо отказаться от нее. Конечно, такое поведение было у многих менеджеров закачек, а не только у FlashGet, но поскольку я использовал именно FlashGet, то о нем и разговор.
Сейчас мы попробуем реализовать подобный мониторинг буфера обмена в Linux с помощью D-Bus. Следующая команда выводит содержимое буфера обмена:
Код: |
qdbus org.kde.klipper /klipper getClipboardContents |
Напишем простенький сценарий, выводящий содержимое буфера обмена, если в буфере обмена есть URL (для простоты мы будем учитывать только http://):
Код: |
#/bin/bash
while true
do
if qdbus org.kde.klipper /klipper getClipboardContents | egrep -q '^(http://)'
then
qdbus org.kde.klipper /klipper getClipboardContents
fi
sleep 1
done |
Сценарий не делает ничего сверхъестественного. Сначала запускается бесконечный цикл (прервать сценарий можно либо нажатием Ctrl + C либо закрытием окна терминала), затем анализируется содержимое буфера обмена. Если оно содержит URL (строку, начинающуюся с http://), то сценарий просто выводит содержимое буфера обмена, а затем просто засыпает на секунду.
Чтобы сценарий закачивал файл, нужно модифицировать его так:
Код: |
#!/bin/bash
while true
do
if qdbus org.kde.klipper /klipper getClipboardContents | egrep -q '^(http://)'
then
in=`qdbus org.kde.klipper /klipper getClipboardContents`
wget $in
fi
sleep 1
done |
Мы сохраняем содержимое буфера обмена в переменной in, а затем передаем ее программе wget, которая и загружает файл.
Конечно, наш "менеджер" загрузок далек от совершенства. Во-первых, нужно научить его реагировать и на FTP-адреса. Во-вторых, если в буфере обмена кроме URL будет еще и произвольный текст, например, "Ссылка http://server/file", то сценарий работать не будет. Тут можно так и оставить (FlashGet тоже не активируется, если в буфере обмена есть еще что-то, кроме URL), а можно с помощью регулярных выражений выделить URL и получить его с помощью wget. В любом случае, все это уже не относится к D-Bus и буферу обмена, поэтому пусть это будет твоим домашним заданием.
Кроме метода getClipboardContents есть метод setClipboardContents, устанавливающий содержимое буфера обмена. Использовать его нужно так:
Код: |
qdbus org.kde.klipper /klipper setClipboardContents текст |
Например:
Код: |
#/bin/bash
while true
do
if qdbus org.kde.klipper /klipper getClipboardContents | egrep -q '^(http://)'
then
qdbus org.kde.klipper /klipper setClipboardContents "копировать URL запрещено"
fi
sleep 1
done |
Пример, конечно, дурацкий, но ничего другого в голову не пришло. Ты уже используй его на свое усмотрение.
Управляем проигрывателем Amarok 2 с помощью D-Bus
Следующие команды аналогичны нажатию кнопок Play, Pause, Next, Prev, Stop, Quit (думаю, что означают эти кнопки, тебе объяснять не нужно):
Код: |
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Play
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Pause
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Next
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop
dbus-send --type=method_call --dest=org.kde.amarok / org.freedesktop.MediaPlayer.Quit |
Вот пример bash-сценария с использованием методов Stop и Play (после "нажатия" Stop делается пауза 5 секунд):
Код: |
#!/bin/sh
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop
sleep 5
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Play |
Отобразить название трека можно так:
Код: |
qdbus org.kde.amarok /Player GetMetadata | grep title: |
Показать имя/название исполнителя можно командой:
Код: |
qdbus org.kde.amarok /Player GetMetadata | grep artist: |
Ну и вывести всю информацию о текущем треке можно так:
Код: |
qdbus org.kde.amarok /Player GetMetadata |
У Amarok2 есть поддержка Last.FM, но для Last.FM поддерживаются только методы Stop и Play:
Код: |
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Stop
sleep 2
dbus-send --type=method_call --dest=org.kde.amarok /Player org.freedesktop.MediaPlayer.Play
|
Еще очень полезный метод GetStatus, возвращающий 4 целых числа:
Первое число: 0 = трек воспроизводится, 1 = пауза, 2 = остановлен (Stop);
Второе число: 0 = последовательное воспроизведение, 1 = случайное воспроизведение;
Третье число: 0 = перейти к следующему элементу после выспроизведения текущего, 1 = повторить текущий элемент;
Четвертое число: 0 = останов, как только будет достигнут последний элемент, 1 = продолжить воспроизведение сначала.
Управление проигрывателями VLC и XMMS
Аналогично, можно управлять и другим проигрывателем - VLC. Вот действия, аналогичные нажатию на кнопку воспроизведения и кнопку паузы:
Код: |
dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play
dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause |
Как только я начал свое знакомство с Linux, лучшим медиа-проигрывателем для Linux был XMMS. Отчасти его популярность заключалась во внешней схожести с популярным в то время Winamp (хотя чего греха таить, в Windows у меня до сих пор установлен Winamp, только последней версии). Недавно наткнулся на полное описание D-Bus интерфейса современной версии XMMS (XMMS 2):
Код: |
http://xmms2.org/wiki/MPRIS#D-Bus |
Если тебе нравится XMMS 2, то эта ссылка будет весьма полезной для тебя.
Интерфейс org.freedesktop.MediaPlayer (MPRIS 1.0 DBus API)
А теперь самое интересное. Внимательно посмотри на команды управления проигрывателем Amarok, затем VLC и XMMS (по указанной ссылке). Не находишь много общего? Все эти проигрыватели используют интерфейс MPRIS. Да, я даже знаю, о чем ты подумал. Берем полное описание MPRIS, например, вот отсюда http://xmms2.org/wiki/MPRIS, подставляем только свой проигрыватель и управляем ним. Можно написать универсальные сценарии управления проигрывателями, в качестве параметра которым передать название проигрывателя.
Интерфейс MPRIS поддерживают следующие проигрыватели:
org.mpris.audacious
org.mpris.bmp
org.mpris.vlc
org.mpris.xmms2
org.kde.amarok
Берем команду dbus-send и вместо значения параметра --dest указываем свой проигрыватель:
Код: |
dbus-send --type=method_call --dest=проигрыватель /Player org.freedesktop.MediaPlayer.Play |
Далее все стандартно. Далее управление проигрывателем осуществляется через интерфейс org.freedesktop.MediaPlayer объекта /Player. А управление списком композиций - через объект /TrackList
А что дальше? Или метод научного тыка
Управлять с помощью D-Bus можно практически любым современным графическим Linux-приложением. Поскольку я, к сожалению, не могу читать ваши мысли, я не могу предусмотреть все трюки, которые ты бы хотел видеть в этой статье. Поэтому дальше мы будем исследовать объекты и методы D-Bus самостоятельно. А я только расскажу, что для этого нужно.
Запусти yakuake (это мой любимый терминал в KDE, поскольку он запускается при нажатии F12) и введи команду:
Код: |
qdbus org.kde.yakuake |
Получишь вот такой вывод:
/
/KDebug
/Konsole
/MainApplication
/Sessions
/Sessions/1
/yakuake
/yakuake/MainWindow_1
/yakuake/sessions
/yakuake/tabs
/yakuake/window
Рис. 1. Команда qdbus org.kde.yakuake
Чуть выше мы говорили о сервисах D-Bus. Так вот, org.kde.yakuake - это и есть название сервиса. В результате команды qdbus org.kde.yakuake ты увидел список объектов сервиса org.kde.yakuake. Если ты знаешь, что такое ООП, то уже догадался, что у каждого объекта есть методы. Просмотреть список методов можно так:
Например:
Код: |
qdbus org.kde.yakuake /yakuake/tabs |
На рис. 2 приведены методы объекта /yakuake/tabs. Например, метод setTabTitle() позволяет установить заголовок вкладки. Для этого методу нужно передать номер сессии и строку - будущий заголовок. Чтобы узнать номер сессии, нужно просмотреть список методов объекта /yakuake/sessions (рис. 3):
Код: |
qdbus org.kde.yakuake /yakuake/sessions |
Рис. 2. Методы объекта /yakuake/tabs
Рис. 3. Методы объекта /yakuake/sessions
Номер (идентификатор) активной сессии возвращается методом activeSessionId(). Чтобы получить номер текущей сессии (под сессией в yakuake подразумевается вкладка), нужно ввести команду:
Код: |
qdbus org.kde.yakuake /yakuake/sessions activeSessionId |
Синтаксист такой:
Код: |
qdbus сервис объект метод |
Напишем небольшой сценарий, изменяющий название вкладки. Запусти KWrite и введи следующий код:
Код: |
#!/bin/bash
id=`qdbus org.kde.yakuake /yakuake/sessions activeSessionId`
echo $id
qdbus org.kde.yakuake /yakuake/sessions setTabTitle $id "произвольный текст" |
На рис. 4 приведен результат этого сценария - заголовок вкладки был изменен на "Denis". А на рис. 5 приведен сам сценарий в окне KWrite.
Рис. 4. Результат работы сценария
Рис. 5. Сценарий sessions.sh
Сценарий можно и усовершенствовать. Можно сделать так, чтобы он принимал текст из командной строки (в качестве первого параметра) - тогда сценарий будет изменять заголовок текущей вкладки:
Код: |
#!/bin/bash
id=`qdbus org.kde.yakuake /yakuake/sessions activeSessionId`
qdbus org.kde.yakuake /yakuake/sessions setTabTitle $id $1 |
Кому не нравится изучать объекты и методы D-Bus в терминале, могут использовать утилиту qdbusviewer, предоставляющую более удобный интерфейс для просмотра списков объектов и методов D-Bus (рис. 6.).
Рис. 6. Утилита qdbusviewer
Точное описание объектов и методов ты найдешь на страничке разработчиков той или иной программы. А вот что касается самой D-Bus, то настоятельно рекомендую ознакомиться вот с этим руководством:
http://dbus.freedesktop.org/doc/dbus-tutorial.html
Изучать D-Bus методом научного тыка, что мы и сделали, то есть путем вывода объектов и методов, тоже вполне можно. Если ты немного знаешь английский, то догадаться, для чего служит тот или иной метод - не сложно. Но документация есть документация. Порой некоторые методы работают не так, как нам этого хочется, а документация объяснит, почему так происходит. |
|
Вернуться к началу |
dhsilabs@jabber.ru |
|
![](templates/subSilver/images/spacer.gif) |
ruslan89
Завсегдатай
Зарегистрирован: 09.01.2010 Сообщения: 799
|
|
|
|
Отлично!!! Как раз начал интересоваться сием чудом! Спасибо!!! ![Neutral](images/smiles/icon_neutral.gif) |
|
Вернуться к началу |
|
![](templates/subSilver/images/spacer.gif) |
Anderson
Завсегдатай
![](images/avatars/6679008954efcfba216cc5.gif)
Зарегистрирован: 08.07.2006 Сообщения: 642 Откуда: localhost
|
|
|
|
Действительно очень хорошая вещь. От себя могу добавить, что через DBus писал бота к LibPurple (Pidgin) и вешал его на вконтактовский джаббер, поскольку у меня оператор "life:)", и я могу сидеть бесплатно на вконтакте через 0.vk.com. Бот позволял бесплатно лазить по башах и получать статьи из википедии.
Алсо, для перехода в слип тоже юзаю DBus:
Код: |
[anderson@arch ~/src/http]$ cat /sh/suspend
#!/bin/bash
xscreensaver-command -lock
dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Suspend int32:0 |
_________________ ArchLinux + Enlightenment 17 (E17) |
|
Вернуться к началу |
|
![](templates/subSilver/images/spacer.gif) |
|
|
 Главная страница сайта
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|