Dbus linux что это

Обновлено: 30.06.2024

Используя межпрограммный интерфейс D-Bus, можно управлять поведением любого современного графического Linux-приложения извне — из своих скриптов или повесив нужное действие на сочетание клавиш. В этой статье мы рассмотрим несколько полезных трюков с D-Bus, которые пригодятся любому пользователю.

Вкратце о D-BUS

Чтобы ты понимал, о чем идет речь, нужно разобраться, как работает D-Bus, и что это вообще такое. Сразу предупреждаю, сейчас будет немного скучно. Но без теории никак. Иначе вместо того, чтобы практически использовать D-Bus, ты ограничишься только трюками из этой статьи.

D-Bus — это система межпроцессного взаимодействия, которая обеспечивает тесную связь десктопных приложений между собой, и связь между десктопными приложениями и системными сервисами. Например, через D-Bus программы могут узнать о наличии/ отсутствии сети у Network Manager'а; твой музыкальный плеер переключится на следующий трек и сообщит IM-клиенту название композиции, причем твои собеседники увидят ее у тебя в статусе; рабочий стол сменит фоновую картинку; все окна с рабочих столов выстроятся в режиме scale; автоматически подмонтируется вставленное USB-устройство (даже если нет прав рута, связка HAL + D-Bus + pmount) и т.д.

Что интересно, D-Bus не зависит от конкретной среды (KDE, GNOME, Xfce…), но при этом прекрасно интегрируется в каждую из них. В основе структуры 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-сервер может потушить экран. Чтобы обойти эту «фичу», нужно ввести команду:

$ xset dpms 0 0 0

Вернемся к методу SimulateUserActivity. Метод, как следует из его названия, имитирует активность пользователя. Его нужно вызывать периодически. Но не будешь же ты вводить приведенную выше команду, скажем, каждые 30 секунд? Тогда можно набросать небольшой сценарий:

Сценарию нужно передать командную строку. Да, именно командную строку, тогда скрипт запустит приложение и будет имитировать активность пользователя. Сохрани сценарий как /usr/bin/simulate. После этого установи права доступа и запускай:

$ sudo chmod +x /usr/bin/simulate
$ simulate mplayer film.avi

Действительно, у MPlayer есть параметр '-stopxscreensaver', но у других проигрывателей подобного параметра может и не оказаться.

Трюки с буфером обмена

В Windows я использовал довольно неплохой менеджер закачек — FlashGet. Он активировался, как только в буфере обмена появлялась ссылка. Всплывало окно, где нужно было либо подтвердить закачку, либо отказаться от нее. Сейчас мы попробуем реализовать подобный мониторинг буфера обмена в Linux с помощью D-Bus. Следующая команда выводит содержимое клипборда:

$ qdbus org.kde.klipper /klipper \
getClipboardContents


then
in='qdbus org.kde.klipper /klipper \
getClipboardContents'
wget $in
fi

Управляем проигрывателем 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 \
/ org.freedesktop.MediaPlayer.Quit

Кстати, у Amarok2 есть поддержка Last.FM, но для этого сервиса поддерж иваются только методы Stop и Play. Приведу воркэраунд для пропуска текущей песни:

Вывести всю информацию о текущем треке можно следующим образом:

$ qdbus org.kde.amarok /Player GetMetadata

Еще очень полезный метод GetStatus, возвращающий 4 целых числа:

  • Первое число: 0 — трек воспроизводится, 1 — пауза, 2 — остановлен;
  • Второе число: 0 — последовательное воспроизведение, 1 — случайное воспроизведение;
  • Третье число: 0 — перейти к следующему элементу после воспроизведения текущего, 1 — повторить текущий элемент;
  • Четвертое число: 0 — остановить воспроизведение, как только будет достигнут последний элемент, 1 — продолжить воспроизведение с начала.

Управление проигрывателями VLC и XMMS

Аналогично можно управлять и другим проигрывателем — VLC. Вот действие, аналогичное нажатию на кнопку воспроизведения:

$ dbus-send --print-reply --session --dest=org.mpris.
vlc /Player org.freedesktop.MediaPlayer.Play

Интерфейс org.freedesktop.mediaplayer (MPRIS 1.0 DBUS API)

Все популярные проигрыватели, такие как Amarok, VLC, XMMS, Audacious, BMPx, используют интерфейс MPRIS. Следовательно, можно написать универсальный сценарий управления проигрывателями, в качестве параметра которому передавать название плеера. Берем команду dbus-send и вместо значения параметра '--dest' указываем своего фаворита:

$ dbus-send --type=method_call --dest=проигрыватель \
/Player org.freedesktop.MediaPlayer.Play

Далее все стандартно. Управление проигрывателем осуществляется через интерфейс org.freedesktop.MediaPlayer объекта /Player. А управление списком композиций — через объект /TrackList.

Регулировка громкости

Установить уровень громкости можно с помощью метода VolumeSet:

$ dbus-send --type=method_call --dest=проигрыватель \
/Player org.freedesktop.MediaPlayer.VolumeSet значение

Значение может быть в диапазоне 0…100. 0 — звук выключен, 100 — максимальная громкость. Например:

$ qdbus org.kde.amarok /Player VolumeSet 90

Узнать текущее значение громкости можно методом VolumeGet.

А что дальше? Или метод научного тыка

С помощью 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

В результате ты получишь список объектов сервиса org.kde.yakuake. Если ты знаешь, что такое ООП, то уже догадался, что у каждого объекта есть методы. Просмотреть список методов можно так:

qdbus сервис объект

$ qdbus org.kde.yakuake /yakuake/tabs

Приведенная выше команда выводит методы объекта /yakuake/tabs. Например, метод setTabTitle() позволяет установить заголовок вкладки. Для этого методу нужно передать номер сессии и строку — будущий заголовок. Чтобы узнать номер сессии, посмотрим на список методов объекта /yakuake/sessions:

$ qdbus org.kde.yakuake /yakuake/sessions

Номер (идентификатор) активной сессии возвращается методом activeSessionId(). Чтобы получить номер текущей сессии (под сессией в yakuake подразумевается вкладка), нужно ввести команду:

$ qdbus org.kde.yakuake /yakuake/sessions \
activeSessionId

qdbus сервис объект метод

Напишем сценарий, изменяющий заголовок текущей вкладки:

Этот скрипт можно и усовершенствовать. Например, сделать так, чтобы он принимал текст из командной строки (в качестве первого параметра) и подставлял его в заголовок текущей вкладки:

Заключение

Кобра, мыло и все остальные

Приложения в рамках одной среды рабочего стола должны тесно взаимодействовать между собой. В KDE не так давно для этого использовалась система DCOP (Desktop COmmunication Protocol), которая в настоящее время заменена на D-Bus. Кроме DCOP существовала возможность коммуникации с помощью CORBA, SOAP или XML-RPC. Но CORBA требует много системных ресурсов, а SOAP и XML-RPC предназначены больше для веб-сервисов.

Если вы достаточно давно пользуетесь операционной системой Linux, то, наверное, уже не раз слышали о сервисе DBus. Он фигурирует в различных логах программ, инструкциях по настройке системы, а также вы можете видеть сервис DBus-daemon, который непонятно зачем загружается при старте системы.

В этой статье мы попытаемся разобраться, что такое DBus, зачем он нужен, а также как его можно использовать для эффективного управления приложениями в системе.

Что такое Dbus?

Dbus или Desktop Bus - это система, которая используется в основном в операционной системе Linux для того, чтобы различные приложения и сервисы могли общаться между собой. Но с помощью Dbus могут взаимодействовать не только приложения, но и пользователи с приложениями.

По сути, DBus состоит из управляющего демона, API для языков программирования, с помощью которых приложения могут взаимодействовать с системой и консольного клиента.

Объекты Dbus

Путь объекта DBus состоит из трех частей:

Несколько примеров объектов:

Интерфейсы имеют очень похожий путь на путь объекта, в некоторых случаях, имя интерфейса совпадает с именем объекта, но если интерфейсов несколько, то они могут отличаться. В отличие от объекта имя интерфейса разделено слэшем. Вот несколько примеров имен интерфейсов, в скобках я привел объекты, в которых есть эти интерфейсы:

  • /org/mpris/MediaPlayer2/Player (org.mpris.MediaPlayer2.VLC)
  • /org/PluseAudio/ServerLookup1 (org.PluseAudio1)

Доступные объекты Dbus

sudo apt install qttools5-dev-tools

Запустив программу через главное меню вы увидите вот такое главное окно:

dbus

Здесь вы можете увидеть на левой панели список доступных объектов, на правой - пути к интерфейсу внутри объекта и методы. Внизу консоль, в которую выводится информация об успешности ваших действий.

Как использовать Dbus?

Обращаться к сервисам Dbus можно с помощью консольной утилиты dbus-send. Рассмотрим ее синтаксис:

$ dbus-send опции --dest адрес_объекта интерфейс метод параметры

Рассмотрим опции утилиты:

Получаем список сетевых адаптеров NetworkManager:

Включим музыку в плеере VLC:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play

Поставим на паузу:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause

Здесь org.mpris.MediaPlayer2.vlc - объект, интерфейс - /org/mpris/MediaPlayer2, метод - org.mpris.MediaPlayer2.Player.Pause

Методы могут получать параметры, например, перемотаем наш трек на несколько секунд:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Seek int64:10000000

Узнать тип переменной можно тоже с помощью qdbusviewer. Кликните по методу правой кнопкой и выберите Call, в открывшемся диалоговом окне будет предложено ввести значение переменной, а также указан ее тип.

Кроме методов, здесь есть переменные. Понять с чем мы имеем дело, методом или переменной можно тоже с помощью qdbusviewer. Для методов будет написано method, для переменных property. Но посмотреть значение переменной не так просто, для этого используется такая конструкция:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Volume

Вместо того чтобы обратиться напрямую к переменной интерфейса, мы используем метод org.freedesktop.DBus.Properties.Get объекта /org/mpris/MediaPlayer2 и передаем ему две строки. Имя интерфейса и имя переменной. Данный пример показывает, как посмотреть текущую громкость VLC.

Установить значение переменной еще сложнее. Для этого используется метод org.freedesktop.DBus.Properties.Set:

dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set string:org.mpris.MediaPlayer2.Player string:Volume variant:double:1.1

Пример изменяет громкость воспроизведения VLC. Этот метод принимает уже три параметра две уже знакомые нам строки и новое значение переменной. Значение переменной имеет тип variant и ему нужно задать нужный тип переменной, в нашем случае нужна double. Посмотреть какой тип переменной нужен вам можно в qdbusviewer, кликните по переменной правой кнопкой мыши и нажмите Set Value. Здесь кроме поля ввода значения вы увидите нужный тип переменной.

Выводы

Теперь вы знаете не только что такое Dbus, но и все необходимые основы, чтобы использование Dbus было для вас достаточно простым в вашей системе и вы могли применять его на полную для управления своими программами. Нашли интересную команду Dbus, которая будет полезна другим пользователям? Напишите в комментариях!

В процессе разработки нескольких Интернет-сервисов мы заметили, что значительная часть их функционала является общей, и руководствуясь принципом DRY (Don't Repeat Yourself — не повторяйся), приняли решение вынести общий функционал в отдельный модуль.

  • независимость от использующих его сервисов;
  • простота «клиентского» кода;
  • многопоточность и высокая скорость работы.
  1. Реализовать модуль в виде ещё одного веб-сервиса на PHP и делать вызовы из клиентских сервисов используя CUrl или с помощью SOAP. Недостатки этого подхода — медленная работа интерпитируемого языка, затраты на сетевые запросы (ненужные на текущий момент, так как предпологается, что модуль и сервисы будут запущены на одном сервере), сложность реализации разделяемых объектов при паралельных запросах.
  2. Реализовать модуль в виде FastCGI-приложения с использованием многопоточности. К положительным сторонам этого варианта следует отнести: возможность написания модуля на C/C++, что увеличило бы быстродействие и позволило реализовать разделяемые объеты в многопоточной среде. Обращения к модулю из PHP-скриптов, можно было бы осуществить с помощью доменных сокетов Unix, что позволило бы избежать затрат на осуществление ненужных обращений к сети (при расположении сервисов и модуля на одном сервере).
  3. Помимио описанных подходов, наше внимание привлекла система межпроцессного взаимодействия (IPC) D-Bus, широко используемая в Linux в настоящее время. Возможности и характеристики D-Bus, такие как быстродействие, надёжность, настраиваемость, наличие высокоуровневых библиотек-обёрток, показались нам привлекательными и удовлетворяющими наши требования. По сути, использование второго варианта привело бы нас к написанию собственного аналога D-Bus. Далее, встал вопрос о вызовах модуля из клиентского PHP-кода. В Интернете нам встретилось две библиотеки реализующих D-Bus на PHP: от Pecl и японская от GREE Labs. Но, так как мы уже успели написать работающий тестовый пример на Pecl D-Bus, японскую реализацию мы не удостоили должного внимания. Со стороны C++ мы решили использовать QtDBus, по причине знакомства программистов с библиотекой Qt.

«Клиентский» код


В коде происходит вызов метода «sum» из интерфейса «test.iface» у объекта, расположенного по пути "/test", на сервисе «test.service» через системную шину D-Bus. Метод вызывается с двумя целочисленными аргументами. В результате выполнения данного скрипта на сервисе «test.service» должно быть выполнено сложение 42-х и 13-ти, а результат выведен с помощью функции var_dump.

Реализация D-Bus-модуля

При проектировании архитектуры модуля, мы решили использовать в своих целях терминологию ZendFramework (что может показаться странным для программы написааной на C++). Это было обусловленно тем, что такие термины как «сервис», «интерфейс», «объект» уже использовались нами применительно к D-Bus. И, чтобы избежать путаницы, мы взяли понятия «действия» (Action) и «контроллера» (Controller) из ZendFramework.
Под термином «действие» мы решили понимать унаследованный от QThread класс, представляющий собой нить, в которой будет реализован любой необходимый функционал.
А «контроллером» назвали класс, инкапсулирующий вызовы действий в своих методах. При этом, контроллер нужно унаследовать от QObject и QDBusContext.

Головная функция

Приведём код головной функции модуля (файл main.cpp). Здесь происходит регистрация контроллера на системной шине D-Bus.

«Контроллер»

Следует обратить внимание на то, что методы контроллера, открытые для межпроцессорных вызовов по D-Bus, работают последовательно. То есть, если первый клиент осуществляет вызов метода sum, второй должен ждать пока выполнение метода не окончится. Поэтому, мы решили сократить код методов до минимума, чтобы избежать длительного ожидания. Таким образом, при каждом клиентском вызове происходит запуск рабочей нити (действия) и выход из метода.

Рассмотрим класс контроллера (файл TestController.h). Реализацию метода для краткости напишем в заголовочном файле.

«Действия»

В действиях мы будем размещать функционал модуля. Каждому методу контроллера будет соответствовать класс действия. Поэтому целесообразно написать класс Action, базовый для всех действий.

Унаследовав этот класс, мы можем сосредоточится на реализации необходимого функционала не заботясь о деталях взаимодействия с D-Bus. Всё, что нужно сделать, это сохранить параметры в свойствах класса, сложить a и b, и записать результат по ссылке reply().

Конфигурация D-Bus

Откомпилировав описанный выше модуль, мы получим приложение регистрирующее D-Bus-сервис «test.service». Попробуем запустить его. Скорее всего, результат будет следующим:


Для решения данной проблемы необходимо внести изменения в конфигурацию D-Bus. D-Bus предоставляет возможность гибкой настройки безопастности и функционала. Для работы нашего примера достаточно создать в файл: /etc/dbus-1/system.d/dbus-test.conf следующего содержания:


Перезапускать демон D-Bus — нет необходимости. Изменения вступят в силу после сохранения файла.
Повторим запуск модуля и, если он благополучно запустился, попробуем обратится к нему из PHP-скрипта.


Вот и ожидаемый результат: 42 + 13 = 55. Исходники можно взять здесь.

Прикладные программы, ядро операционной системы и даже ваш мобильный телефон могут информировать вас о наступивших событиях, что позволит вам использовать ваш компьютер с максимальным удобством. В этой статье рассказывается о том, как работает D-BUS и как приложения могут использовать эту систему.

D-BUS представляет собой систему межпроцессного взаимодействия (IPC), предоставляющую простой и мощный механизм, с помощью которого приложения могут обмениваться друг с другом информацией и инициировать запросы служб. Система D-BUS была спроектирована с нуля в условиях необходимости удовлетворения запросов современных Linux-систем. Главной задачей D-BUS является замена таких систем удаленных вызовов объектов, как CORBA и DCOP, используемых в GNOME и KDE соответственно. В идеальном случае, система D-BUS может стать унифицированной и гибкой системой межпроцессного взаимодействия для обоих вышеупомянутых окружений рабочего стола, удовлетворяющей их нуждам и используемой для реализации новых возможностей.

Почему система D-BUS уникальна

Последней уникальной возможностью является создание не одной, а сразу двух таких шин: шины системы и шины сессии. Шина системы является глобальной шиной, работающей на уровне системы. Все пользователи системы, имеющие соответствующие права, могут использовать эту шину, что вводит концепцию общесистемных событий. Шина сессии создается во время входа пользователя в систему и работает на уровне пользователя или сессии. Эта шина используется исключительно определенным пользователем в рамках определенной сессии как система межпроцессного взаимодействия и удаленного вызова объектов для пользовательских приложений.

Концепции D-BUS

Почему следует использовать D-BUS

Уровень событий ядра

Уровень событий ядра связан с файловой системой sysfs, являющейся отображением внутренних объектов ядра (kobjects) и расположенной в /sysfs в современных дистрибутивах Linux. Каждая директория sysfs связана с объектом ядра (kobject), являющимся структурой ядра, предназначенной для внутреннего представления объектов; sysfs является иерархией объектов, экспортируемой из ядра в виде файловой системы.

Каждое событие уровня событий ядра моделируется таким образом, что в качестве инициатора приводится путь в файловой системе sysfs. Таким образом, события выглядят как инициированные объектами ядра. Пути из файловой системы sysfs легко приводятся к путям объектов D-BUS, связывая уровень событий ядра и систему D-BUS естественным образом. Уровень событий ядра был впервые представлен в ядре версии 2.6.10-rc1.

Во-вторых, шина сессий предоставляет механизмы межпроцессного взаимодействия и удаленного вызова процедур, предоставляя в перспективе унифицированную систему для GNOME и KDE. Целью D-BUS является создание системы с функциями CORBA, лучшей чем CORBA и системы с функциями DCOP, лучшей чем DCOP, удовлетворяя требованиям обоих проектов и в то же время, предоставляя дополнительные возможности.

К тому же, D-BUS обладает этими возможностями, оставаясь простой и эффективной системой.

Добавление поддержки D-BUS в ваши приложения

Давайте рассмотрим простейшие примеры использования D-BUS в ваших приложениях. Сначала рассмотрим API для языка C, затем перейдем к рассмотрению кода с использованием интерфейса Glib.

Использование API D-BUS для языка C

Использование системы D-BUS начинается с подключения заголовочного файла: Первое, что вам наверняка захочется сделать - это подключиться к существующей шине. Повторим сказанное в предыдущих разделах: D-BUS предоставляет две шины, шину сессии и шину системы. Давайте подключимся к системной шине:

Интерфейс Glib

Glib (произносится как гии-либ) является базовой библиотекой GNOME. Gtk+ (API для создания графических интерфейсов приложений GNOME) и остальные компоненты GNOME используют функции Glib. Glib содержит ряд функций, повышающих удобство использования языка C, функции для поддержки кроссплатформенности, ряд функций для работы со строками и полную реализацию системы работы с объектами и типами - все это на чистом C.

Библиотека Glib представляет систему работы с объектами и цикл ожидания событий (mainloop), позволяющие работать с объектами и событиями даже на C. В API Glib предусмотрено использование этих возможностей. Для начала нам нужно подключить необходимые заголовочные файлы: Glib использует понятие прокси-объектов для представления различных реализаций соединений D-BUS, связанных с определенными службами. Прокси-объект создается при помощи единственного вызова:

В этот раз вместо отправки сигнала, давайте выполним вызов удаленного метода. Эта операция осуществляется при помощи двух функций. Первая функция вызывает удаленный метод, вторая - получает возвращенное значение.

Теперь давайте проверим наличие ошибок и, в случае их отсутствия, получим возвращенное в результате вызова метода значение:

Функция Peel принимает дин параметр в виде целого числа. Если метод возвратит значение, отличное от нуля, он корректно завершился и в переменной ret содержится значение, возвращенное этой функцией. Типы данных, которые принимает определенный метод, описываются при реализации метода. Например, мы не передавали тип DBUS_TYPE_STRING вместо типа DBUS_TYPE_INT32.

Заключение

D-BUS является мощной и простой системой межпроцессного взаимодействия, которая с успехом улучшит интеграцию и расширит функциональность Linux-систем. Пользователи рано или поздно столкнутся со все большим количеством приложений, использующих D-BUS. Имея на руках эту статью, есть все основания рассматривать D-BUS не как ужасную зависимость, а как блестящую особенность системы. На интернет-ресурсах можно найти ряд примеров программ, использующих D-BUS. Разработчики со временем будут вынуждены добавлять поддержку D-BUS в свои приложения. Также существует ряд сайтов с описанием возможностей и примерами использования D-BUS. Конечно же, лучшим справочным материалом является исходный код, и, к счастью, его сейчас очень много.

Читайте также: