Разница между 1.8
и текущей версией
ПротоколWayland.
@@ -12,14 +12,14 @@
'''Композитор''' — программа, отвечающая за отрисовку окон. Она является сервером, к которому подключаются один или несколько '''клиентов''' (GUI-программ которые хотят показывать окна пользователю).
-Каждый клиент может зарегистрировать несколько "поверхностей" (в терминах wayland -- surface). Поверхность можно связать буфером, содержащим пиксели с изображением окна.
+Каждый клиент может зарегистрировать несколько '''поверхностей''' (в терминах wayland -- surface). Поверхность можно связать буфером, содержащим пиксели с изображением окна.
Связанный с поверхностью буфер клиент передаёт в композитор через разделяемую память (shared memory), так же существуют оптимизации, позволяющие передать буфер через GPU.
-'''Поверхность''' это любые данные, которые необходимо отобразить пользователю. Поверхностью может
+Поверхность это любые данные, которые необходимо отобразить пользователю. Поверхностью может
быть иконка курсора мыши, либо окно графического интерфейса, либо всплывающая подсказка, появляющаяся при наведении курсора в определённое место.
Композитор отвечает за позиционирование окон на экране и за обработку запросов от клиентов.
-При начале этого взаимодействия композитор сообщает клиенту список поддерживаемых '''интерфейсов'''.
+При начале взаимодействия с клиентом композитор сообщает ему список поддерживаемых '''интерфейсов'''.
Интерфейс представляет из себя описание некоторого объекта, с которым могут работать и клиент и сервер.
@@ -31,9 +31,9 @@
* wl_seat — интерфейс, описывающий устройства ввода
Все интерфейсы состоят из следующих компонентов
- * '''Метод''' — функция, которую может вызвать клиент, для этого объекта. Сервер регистрирует обработчик на каждый метод интерфейса. Эти обработчики вызываются асинхронно, при обращениях клиента.
+ * '''Запрос''' (request) — функция, которую может вызвать клиент, для этого объекта. Сервер регистрирует обработчик на каждый запрос интерфейса. Эти обработчики вызываются асинхронно, при обращениях клиента.
Пример — метод attach объекта wl_surface (которы присоединяет буфер к surface)
- * '''Событие''' — функция, которую может вызвать сервер для этого объекта. Клиент может регистрировать обработчики, которые будут вызываться асинхронно, при наступлении этого события.
+ * '''Событие''' (event) — функция, которую может вызвать сервер для этого объекта. Клиент может регистрировать обработчики, которые будут вызываться асинхронно, при наступлении этого события.
Интерфейсы (основные и дополнительные) описываются в специальном xml-файле, который по совместительству является и документацией [5].
@@ -41,16 +41,68 @@
- wayland API
-https://t1.rbxcdn.com/1bc7338a17f1c055b58f5e1ac9c46f42
Базовую информацию о том, как писать клиент и сервер настоятельно рекомендуется посмотреть тут [6].
+
+-- Сервер
+
+Работа начинается с того, что сервер создаёт новый объект типа ''wl_display''.
+''wl_display'' является глобальным контекстом, который используется при работе с клиентами.
+Композитору нужен один объект такого типа.
+
+После этого сервер должен создать UNIX-сокет по которому клиенты смогут подключиться к серверу.
+
+==={c}
+struct wl_display *display = wl_display_create();
+char *sockpath = wl_display_add_socket_auto(ctx->display);
+===
+
+Затем серверу необходимо зарегистрировать те интерфейсы и их версии, которые он поддерживает.
+
+==={c}
+struct wl_compositor *compositor = wl_global_create(display, &wl_compositor_interface,
+ 3, userdata, &bind_compositor);
+===
+
+При этом ''wl_compositor_interface'' -- это структура типа ''wl_interface'',
+которая содержит базовое описание интерфейса (имя, версия, количество типов запросов, ...).
+''bind_compositor'' — это функция, которая будет вызвана,
+когда клиент попытается создать объект с этим интерфейсом.
+
+Основной работой bind_compositor будет создание
+нового объекта (в терминах wayland -- ресурса), который будет связан с этим клиентом.
+При создании этого объекта сервер передаёт callback-функции, которые будут обрабатывать запросы клиента.
+
+==={c}
+static const struct wl_compositor_interface compositor_interface = {
+ .create_surface = compositor_create_surface,
+ .create_region = compositor_create_region
+};
+static void bind_compositor(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ struct wl_resource *resource = wl_resource_create(client, &wl_compositor_interface,
+ version, id);
+
+ wl_resource_set_implementation(resource, &compositor_interface, data, NULL);
+}
+===
+
+Помимо функций для обработки запросов ''wl_resource_set_implementation'' позволяет связать с ресурсом
+произвольные пользовательские данные.
+
+Подобным образом происходит работа со всеми интерфейсами в wayland. Сервер регистрирует обработчики запросов на каждый ресурс и в них реализует всю логику работы приложения.
+
+[[https://blog.4castplus.com/hubfs/Imported_Blog_Media/work_in_progress.jpg||350px]]
+
Структура библиотеки:
* структуры данных wl_list, wl_array, ...
* петля событий
* таймеры
* wayland-сигналы — примитив, позволяющий доставлять асинхронные нотификации при возникновении произвольных событий
+
+
- Ссылки
1 https://github.com/wayland-project/wayland
1 https://wayland.freedesktop.org/architecture.html