Основной протокол X Window System

Основной (корневой) протокол X Window System (англ. X Window System core protocol) — формат взаимодействия системы X Window, сетевой оконной системы для растровых видеотерминалов. X Window основана на клиент-серверной модели, то есть один сервер управляет всем вводом-выводом, таким как экран(ы), клавиатура и «мышь», все приложения работают как клиенты, взаимодействуя с пользователем и другими клиентами через сервер. Это взаимодействие и обеспечивается корневым протоколом. Существуют также другие протоколы, которые являются как «надстройками» над корневым, так и совершенно независимыми.

Логотип X Window System

Корневой протокол системы X Window предусматривает только 4 типа пакетов данных, посылаемых асинхронно через сеть: запросы, отклики, события и сообщения об ошибках. Запросы посылаются клиентом в сторону сервера для выполнения последним какого-либо действия (например, создать новое окно) и/или указания серверу послать назад какие-либо данные. Отклик сервера обеспечивает пересылку этих данных клиенту. События рассылаются сервером для уведомления его клиентов о пользовательской активности или другой деятельности на стороне сервера, в которых заинтересован тот или иной клиент. Сообщения об ошибках рассылаются сервером его клиенту в случае ошибок обработки запросов клиента. Запросы могут порождать отклики, события или сообщения об ошибках. Протокол не устанавливает обязательной последовательности передачи пакетов по сети. Существуют расширения корневого протокола со своими запросами, откликами, событиями или сообщениями об ошибках.

Система X появилась в МИТ в 1984 году (текущая версия X11 — в сентябре 1987 года). Её разработчик Боб Шифлер и Джим Гетис в ходе её разработки руководствовались правилом, что корневой протокол должен устанавливать «механизм, а не набор правил-политик». В результате корневой протокол не специфицирует взаимодействие между клиентами, а также между клиентом и пользователем. Они являются предметом дополнительных спецификаций [1], таких как ICCCM и Freedesktop.org и они обычно выполняются автоматически с использованием предзаданного набора виджетов.

Общий обзор

править

Связь между сервером и клиентами осуществляется путём обмена пакетами по каналу. Соединение устанавливается клиентом (как клиент начнёт в протоколе не определено). Кроме того, клиент отправляет первый пакет, содержащий используемый порядок байтов, и информацию о версии протокола, а также ожидаемого клиентом типа аутентификации, для использования сервером. Сервер отвечает, послав обратно пакет с подтверждением или отказом в соединении, или с запросом о дальнейшей аутентификации. Если соединение будет подтверждено, далее отправляется пакет содержащий данные клиенту для использования в последующем взаимодействии с сервером.

 
Пример взаимодействия клиента и сервера

После того как соединение установлено, четыре типа пакетов используются для обмена между клиентом и сервером по каналу:

  1. Request: Клиент запрашивает информацию с сервера или просит выполнить действие.
  2. Reply: Сервер отвечает на запрос. Не все запросы, порождают ответы.
  3. Event: Сервер сообщает клиенту о событиях, таких как ввод с клавиатуры или мыши, перемещение окна, изменение размера или раскрытия на весь экран и т. д.
  4. Error: Сервер посылает пакет с описанием ошибки, если запрос является неправильным. Поскольку запросы ставятся в очередь, то пакеты с сообщением об ошибке порожденные им, не могут быть отправлены немедленно.

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

То, что обычно называют окном в большинстве графических пользовательских интерфейсов в X Window System называется окном верхнего уровня. Термин окно используется также для обозначения окон, которые лежат в другом окне, то есть подокна от родительского окна. Графические элементы, такие как кнопки, меню, иконки и т. д. могут быть реализованы с использованием подокна.

 
Возможное расположение окон: 1) корневое окно на весь экран; 2) и 3) окна наивысшего уровня, 4) и 5) — дочерние окна для 2). Области вне экрана отбрасываются

Клиент может запросить создание окна. Точнее, он может запросить создание подокна в существующем окне. В результате, окна, созданные клиентами, расположены в виде дерева (иерархии). Корень этого дерева в корневом окне, которое является специальным окном создаваемым автоматически при запуске сервера. Все остальные окна, прямо или косвенно подокна корневого окна. Окна верхнего уровня являются прямыми подокнами корневого окна. Ясно, что корневое окно такого же размера как и экран (хотя, может быть и больше, в этом случае пользователь может перемещать видимую область), и лежит в основе всех остальных окон.

Содержимое окна не всегда гарантированно будет сохранено со временем. В частности, содержимое окна может быть уничтожено при перемещении окна, изменении размеров, перекрытия другими окнами, и в общем сделано полностью или частично не видимым. В частности, содержание теряется, если X сервер не поддерживает хранение содержимого окна во вспомогательной памяти. Клиент может запросить сохранить содержимое окна во вспомогательную память, но сервер не обязан этого делать. Таким образом, клиенты не могут считать, что существует поддержка вспомогательной памяти. Если видимая часть окна имеет неопределенное содержимое, событие направляет сообщение клиенту, что содержание окна должно быть нарисовано снова.

Каждое окно имеет соответствующий набор атрибутов, таких как геометрия окна (размер и положение), фоновые изображения, запрошено ли сохранение этого во вспомогательную память, и т. д. Протокол содержит запросы к клиенту для проверки и изменения атрибутов окна.

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

 
Анатомия окна FVWM. Пространство белого цвета это окно созданное и видимое клиентским приложением.

Декоративная рамка и заголовок (возможно, в том числе и кнопки), которые обычно наблюдаются вокруг окон создаются диспетчером окон, а не клиентом, который создает окно. Диспетчер окон так же управляет вводом связанным с этими элементами, такими, как изменение размера окна, когда пользователь нажимает и тащит оконную рамку. Клиенты обычно работают в окне, они созданы без учёта изменений производимых диспетчером окон. Так же надо учитывать те диспетчера окон, которые заменяют общее корневое родительское окно для окон верхнего уровня. Сейчас это делают большинство диспетчеров окон. С точки зрения основного протокола, диспетчер окон, является таким же клиентом как и другие приложения.

Данные об окне можно получить, запустив программу xwininfo. Запустив её из командной строки с аргументом —tree, эта программа показывает дерево подокон из окна, а также их идентификаторы и геометрические данные.

Пиксельные карты и области рисования

править

Растровое изображение хранится в памяти сервера, на экране не отображается, но может быть нарисовано в окне целиком или частично. Содержимое окна можно сохранить в виде растрового изображения. Это позволяет реализовать двойную буферизацию. Графические операции, применимые для окон, также применимы для растровых изображений.

Окна и растровые изображения называют областями рисования. Содержимое областей рисования хранится на сервере. Клиент может послать запрос на перенос содержимого области с сервера к клиенту или наоборот.

Графические контексты и шрифты

править

Клиент может запросить несколько графических операций, таких как, очистка области, копирование области в другую, прорисовка точек, линий, прямоугольников и текста. Кроме очистки, все операции могут выполняться над всеми областями рисования.

Большинство запросов о графических операциях включают в себя графический контекст — структуру данных, содержащую параметры графических операций. Графический контекст включает в себя цвет переднего плана, цвет фона, шрифт текста и другие параметры. При запросе графических операций, клиент включает в себя графический контекст. Не все параметры графического контекста влияют на работу: например, шрифт не влияет на прорисовку линии.

Основной протокол предписывает использовать шрифты на стороне сервера. Такие шрифты хранятся в виде файлов, а сервер осуществляет к ним доступ непосредственно через локальную файловую систему или через сеть с помощью другой программы, называемой сервером шрифтов. Клиент может запросить список шрифтов, доступных на сервере, может запросить загрузку какого-то шрифта на сервер (если такого шрифта ещё нет на сервере) или выгрузить шрифт (если он не используется другими клиентами) на сервере. Клиент может запросить информацию о шрифте (например, ascent шрифта) и место, занимаемое конкретной строкой, когда прорисовывается определенным шрифтом.

 
xfontsel позволяет увидеть начертание символов в шрифте.

Имена шрифтов на уровне основного протокола X Window — это произвольные строки. Соглашение, логически описывающее шрифт для X, определяет, как именно должны быть названы шрифты в соответствии с их атрибутами. Эти соглашения также указывают значения дополнительных свойств, которые могут иметь шрифты.

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

Прорисовка шрифтов на стороне сервера в настоящее время считается устаревшей, и большинство клиентов (GTK, Qt) уже занимаются прорисовкой шрифтов. Для прорисовки шрифтов клиенты используют библиотеки Xft или cairo, и расширения XRender. Спецификация основного протокола не описывает прорисовку шрифтов на стороне клиента.

Ресурсы и идентификаторы

править

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

  • окно;
  • пиксельная карта;
  • шрифт;
  • цветовая карта (таблица цветов, описание находится ниже);
  • графический контекст.

Эти объекты называются ресурсами. Когда клиент запрашивает создание одного из таких ресурсов, он также указывает его идентификатор. Например, для создания нового окна, клиент определяет как атрибуты окна (родителей, ширина, высота и т. д.), так и связанный с окном идентификатор.

Идентификаторы являются 32-разрядными целыми числами, три старших бита которых всегда равны нулю. Каждый клиент имеет свой собственный набор идентификаторов, который можно использовать для создания новых ресурсов. Этот набор выдаётся сервером в пакете подтверждения (пакете, отправляемом клиенту для сообщения о принятии соединения) и представлен в виде двух чисел. Клиенты выбирают идентификаторы из этого набора таким образом, что разные объекты имели разные идентификаторы.

После создания ресурса его идентификатор может использоваться клиентом в запросах к серверу. Некоторые операции влияют на данные ресурсы (например, запрос на перемещение окна), другие запросы ресурсов, хранящихся на сервере (например, запросы атрибутов окон).

Идентификаторы являются уникальными не только для клиента, но и для сервера. Так два окна не могут иметь один и тот же идентификатор, даже если созданы двумя разными клиентами. Клиент может получить доступ к любому объекту по его идентификатору (даже к объекту другого клиента).

В результате два клиента, подключенных к одному серверу, могут использовать один и тот же идентификатор для ссылок на один и тот же ресурс. Например, если клиент создает окно с идентификатором 0x1e00021 и передаёт этот номер 0x1e00021 в другое приложение (с помощью любых доступных средств, например, сохраняя этот номер в файл, также доступный для других приложений), то это другое приложение может работать на том же самом окне. Такая возможность, например, использует версией X Window программы Ghostview: эта программа создает окно-потомка, сохраняет его идентификатор в переменной среды, и вызывает Ghostscript, которая рисует содержимое файла PostScript и отображает в этом окне [8].

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

События

править

События — пакеты, посланные сервером клиенту, c сообщением, что ожидаемое клиентом, случилось. Например, событие посылается, когда пользователь нажимает клавишу или нажимает кнопку мыши. События могут использоваться не только для ввода: например, события посылают указание на создание новых подокон в данном окне.

Каждое событие связано с окном. Например, если пользователь щёлкает мышью, событие будет относиться к окну, над которым был курсор в момент щелчка. Пакет события будет содержать идентификатор этого окна.

Клиент может запросить сервер отправить событие другому клиенту. Это используется для организации взаимодействия между клиентами. Такое события, например, генерируется при запросе клиентом выделенного текста и отправляется сервером клиенту, владеющему окном с выделенным текстом.

Событие Expose отправляется сервером, если изображение области окна клиента было стёрто из памяти, а окно становится видимым. Изображение окна стирается из памяти, если окно было свёрнуто, перекрыто другим окном и в других случаях.

 
Пример. При нажатии клавиши в окне сервер создаёт событие. Если в маске событий окна установлен соответствующий бит, событие будет отправлено клиенту.

Большинство типов событий отправляются клиенту только если он ранее заявил о своей заинтересованности в них. Например, клиент может быть заинтересован в событиях связанных с клавиатурой, но не связанных с мышью. Несмотря на это, некоторые типы событий передаются клиентам, даже если они их специально не запрашивали.

Клиент выбирает нужные типы событий путём установки особого атрибута окна — маски событий. Например, для начала рисования содержимого окна клиент должен получить событие Expose. Сервер, однако, пошлёт это событие только, если клиент установил соответствующий бит в маске события окна.

Различные клиенты могут запрашивать события одного и того же окна. Они могут даже установить различные маски событий на одном и том же окне. Например, один клиент может запрашивать только события клавиатуры, а другой — только события мыши. Однако, существует несколько типов событий, которые могут быть доставлены только одному клиенту. В частности, это события сообщений кликов мышью и некоторые изменения, связанные с управлением окном.

xev — программа, которая показывает события по отношению к окну. В частности, команда xev -id WID запрашивает все возможные события относительно окна с идентификатором WID и выводит их.

Примеры

править

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

  1. Клиент открывает соединение с сервером и посылает начальный пакет с указанием порядка байтов который он использует.
  2. Сервер принимает соединение (авторизация не используется в данном примере), отправив соответствующий пакет, который содержит другие сведения, такие как идентификатор корневого окна (например, 0x0000002b), и идентификаторы которые клиент может создать.
  3. Клиент запрашивает создание графического контекста по умолчанию с идентификатором 0x00200000 (этот запрос, как и другие запросы такого типа, например, не генерируют ответы от сервера).
  4. Клиент запрашивает у сервера создание окна верхнего уровня (то есть, он определяет родителя для корневого окна 0x0000002b) с идентификатором 0x00200001, размер 200x200, позиции (10,10) и т. д.
  5. Клиент запрашивает изменение атрибутов окна 0x00200001, указав на заинтересованность в получении событий Expose и KeyPress.
  6. Клиент запрашивает отображение окна 0x00200001 (т. е. оно будет показано на экране).
  7. Когда окно становится видимым и его содержимое должно быть прорисовано, то сервер посылает клиенту событие Expose.
  8. В ответ на это событие, клиент запрашивает прорисовку ящика путём отправка запроса PolyFillRectangle с указанием идентификатора окна 0x00200001 и графического контекста 0x00200000.

Если окно перекрывает другое окно и не перекрывает его вновь, при условии что резервное хранилище не управляется, то:

  1. Сервер отправляет другое событие Expose с сообщением клиенту о том, что его окно отрисовывается снова.
  2. Клиент перерисовывает окно, снова посылая серверу запрос PolyFillRectangle.

На уровне протокола цвет представлен 32-битным беззнаковым целым числом, называемым pixelvalue. Следующие элементы принимают участие в представление цвета:

  1. глубина цвета (colordepth);
  2. карта цветов (colormap ) — таблица, содержащая значения интенсивности красной, зелёной и синей составляющих цвета;
  3. визуальный тип (visual type), определяющий способ использования таблицы для представления цветов.

В простейшем случае, карта цветов содержит триаду RGB в строке. pixelvalue x представляет собой x-ю строку в таблице. Если клиент может изменять записи в карте цветов, то представление отождествляется с визуальным классом PseudoColor. Визуальный класс StaticColor схож, но клиент не может менять записи в таблице цветов.

Всего доступно 6 визуальных классов. Каждый определяется различным способом представления триады RGB с pixelvalue. PseudoColor и StaticColor — первые два. Следующие два — GrayScale и StaticGray, отличаются тем, что показывают только оттенки серого.

Оставшиеся два визуальных класса отличаются от указанных выше тем, что не используют значение триады pixelvalue, а используют три различных таблицы для красного, зелёного и синего значения интенсивности.

Согласно представлению цветов, pixelvalue преобразует в RGB триаду в следующих случаях:

  1. pixelvalue виделась, как последовательность бит;
  2. эта последовательность нарушается в трёх частях;
  3. каждая из этих трёх частей из бит виделась как целое и использовалась как индекс для поиска значения в каждой из трёх раздельных таблиц.

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

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

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

Для каждого визуального типа, подтверждающий пакет содержит оба этих идентификатора и актуальные параметры содержимого (визуальный тип и т. д.) Клиент сохраняет эту информацию, так как в дальнейшем он не сможет запросить эту информацию снова. Кроме того клиенты не могут сменить или создать новые визуальные типы. Запросы о создании нового окна включают глубину цвета и идентификатор визуального типа для отображения цветов в этом окне.

Карты цветов используются независимо от аппаратуры, контролирующей экран (т. е., видеокарта может использовать палитру (таблицу цветов), а может и не использовать). Серверы используют карты цветов, даже если аппаратура не использует палитру. Когда аппаратура использует палитры, ограниченное количество карт цветов можно установить. В частности, карты цветов, устанавливаются, когда аппаратура показывает согласующиеся цвета. Клиент может запросить сервер установить карту цветов. Однако это может потребовать удаления другой карты цветов: эффектом использования удалённой карты цветов будет изображение с некорректными цветами, эффект двойной цветовой вспышки или цвета высокой интенсивности. Эта проблема может быть решена использованием стандартных карт цветов. Это цветовые карты с предустановленными ассоциациями между pixelvalues и цветами. Благодаря этому качеству, стандартные карты цветов могут использоваться различными приложениями.

Создание карт цветов регулируется соглашением ICCCM. Стандартные карты цветов определяются ICCCM и спецификацией Xlib.

Частью системы цветов X является Система управления цветом X (X Color Management System (xcms)). Эта система появилась вместе с X11R6 Release 5 в 1991 году. Эта система содержится в виде нескольких дополнительных возможностей Xlib, находящихся в серии функций, имена которых начинаются с Xcms. Система определяет аппаратно-независимые цветовые схемы которые уже могут быть конвертированы в аппаратно-зависимые системы RGB. Система содержит функции Xlib Xcms*, а также Соглашение цветовой характеристики устройства (X Device Color Characterization Convention (XDCCC)) которая описывает как преобразуются различные аппаратно-независимые цветовые системы в аппаратно-зависимые RGB цветовые системы. Эта система поддерживает цветовые системы CIEXYZ, xyY, CIELUV и CIELAB, а также TekHVC.

Литература

править

Ссылки

править

Примечания

править
  1.  (англ.) Jim Gettys, Open Source Desktop Technology Road Map Архивировано 2 января 2006 года.