Перейти к содержимому

X11 linux что это

  • автор:

Как работает протокол X11 на самом нижнем уровне

X11 это тот механизм на чем работает весь графический интерфейс Unix подобных ОС.

Но мало кто знает как он работает на самом деле. Потому что с годами он оброс слоями и слоями библиотек, которые стремятся скрыть саму сущность протокола.

А протокол в своей сути прекрасен. Он лаконичен и почти совершенен.

В Интернете есть полная документация по протоколу. Но дело в том, что эта документация большая, написана не совсем ясным языком и по сути представляет просто спецификация. Важные моменты никак не обозначены, а как использовать тоже оставлено на фантазии читателя.

А все книги и статьи по использованию X11 описывают это через библиотеки прокладки типа XLib и XCB, и даже, что хуже, GTK или Qt.

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

Как бы то ни было, если кому-то интересно как все работает на самом деле, пожалуйста под кат.

Суть

Суть X11 в том, что есть программа сервер (X server) которая ожидает подключения и выполняет те команды которые получает от клиента. Например создать графическое окно. Нарисовать что-то и так далее.

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

Клиент, по сути это консольная программа, которая с графикой не имеет ничего общего, кроме этого сетевого соединения.

Протокол

Весь основной протокол описан в документе X Window System Protocol

Самое полезное в этом документе, это приложение «B», где описано побайтно что и куда присылается и принимается.

Я буду цитировать отрывки, чтобы иллюстрировать текст.

Идентификаторы

Все объекты в X имеют идентификатор. Это 32 битовое число, которое генерирует клиент и передает серверу, чтобы обозначить создаваемый объект. Например окно, курсор, картинка и т.д.

Другой тип идентификаторов это ATOM. Атомы это тоже 32 битовые числа, но их генерирует сервер. Клиент передает серверу какую-то символьную строку, а сервер в ответ дает число. Одинаковым строкам всегда соответствует одинаковое число. Это похоже на хеширование, но сделано по другому – сервер просто хранит список строк и присваивает им номера. Если какой-то клиент запросит атом для строки которая уже находится в списке, ему возвращают номер строки в списке.

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

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

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

Стандартные атомы

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

atomPRIMARY = 1 atomSECONDARY = 2 atomARC = 3 atomATOM = 4 atomBITMAP = 5 atomCARDINAL = 6 atomCOLORMAP = 7 atomCURSOR = 8 atomCUT_BUFFER0 = 9 atomCUT_BUFFER1 = 10 atomCUT_BUFFER2 = 11 atomCUT_BUFFER3 = 12 atomCUT_BUFFER4 = 13 atomCUT_BUFFER5 = 14 atomCUT_BUFFER6 = 15 atomCUT_BUFFER7 = 16 atomDRAWABLE = 17 atomFONT = 18 atomINTEGER = 19 atomPIXMAP = 20 atomPOINT = 21 atomRECTANGLE = 22 atomRESOURCE_MANAGER = 23 atomRGB_COLOR_MAP = 24 atomRGB_BEST_MAP = 25 atomRGB_BLUE_MAP = 26 atomRGB_DEFAULT_MAP = 27 atomRGB_GRAY_MAP = 28 atomRGB_GREEN_MAP = 29 atomRGB_RED_MAP = 30 atomSTRING = 31 atomVISUALID = 32 atomWINDOW = 33 atomWM_COMMAND = 34 atomWM_HINTS = 35 atomWM_CLIENT_MACHINE = 36 atomWM_ICON_NAME = 37 atomWM_ICON_SIZE = 38 atomWM_NAME = 39 atomWM_NORMAL_HINTS = 40 atomWM_SIZE_HINTS = 41 atomWM_ZOOM_HINTS = 42 atomMIN_SPACE = 43 atomNORM_SPACE = 44 atomMAX_SPACE = 45 atomEND_SPACE = 46 atomSUPERSCRIPT_X = 47 atomSUPERSCRIPT_Y = 48 atomSUBSCRIPT_X = 49 atomSUBSCRIPT_Y = 50 atomUNDERLINE_POSITION = 51 atomUNDERLINE_THICKNESS= 52 atomSTRIKEOUT_ASCENT = 53 atomSTRIKEOUT_DESCENT = 54 atomITALIC_ANGLE = 55 atomX_HEIGHT = 56 atomQUAD_WIDTH = 57 atomWEIGHT = 58 atomPOINT_SIZE = 59 atomRESOLUTION = 60 atomCOPYRIGHT = 61 atomNOTICE = 62 atomFONT_NAME = 63 atomFAMILY_NAME = 64 atomFULL_NAME = 65 atomCAP_HEIGHT = 66 atomWM_CLASS = 67 atomWM_TRANSIENT_FOR = 68

Запросы

Все запросы в X11 бинарные, с полями разной длины. По сути, здесь есть поля длиной в 1 байт, 2 байта и 4 байта.

Первые 4 байта запроса всегда присутствуют и всегда содержат одинаковую информацию:

Смещение Длина Содержание
0 1 Код команды. Основной протокол использует только значения от 1 до 127, а значения больше 127 выделены расширениям.
1 1 Подкоманда или какой-то параметр запроса длиной в 1 байт или не используется.
2 2 Длина всего запроса в двойных словах (4 байта).

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

Чтобы не быть слишком голословным покажу простой пример:

Запрос «DestroyWindow» кодируется вот так (допустим хотим закрыть окно с ID 0x12345678):

Смещение Длина Значение Заметки
0 1 0x03 3 это код операции DestroyWindow
1 1 0x00 Не используется. Значение может быть любое. Сервер все-равно его не смотрит.
2 2 0x0002 Длина запроса 2 двойных слова или 8 байт.
4 4 0x12345678 Идентификатор окна.

Или в итоге, по сокету уходит вот что: 03 00 02 00 78 56 34 12

Получив этот запрос, X сервер закроет окно с идентификатором 0x12345678

В документации протокола (а точнее в приложении), вот это запрос DestroyWindow описан следующим синтаксисом:

 1 4 opcode 1 unused 2 2 request length 4 WINDOW window

А сейчас что-то посложнее: «CreateWindow».

Предварительно надо выбрать идентификатор окна. Выберем опять 0x12345678 чтобы было попроще.
Еще понадобиться идентификатор коренного окна (это служебное окно, которое занимает весь дисплей и является родительским для всех окон верхнего уровня. Допустим его идентификатор 0x9abcdef0 (а откуда взять реальные значения, я расскажу немножко позже).

Смещение Длина Имя поля Значение Заметки
0 1 opcode 0x01 Операция CreateWindow == 1
1 1 depth 0x00 Глубина цвета окна. 0 значит CopyFromParent
2 2 length 0x0008
4 4 wid 0x12345678 Идентификатор который выбрали.
8 4 parent 0x9abcdef0
12 2 x 0x64 Это X координата верхнего левого угла нашего окна.
14 2 y 0x65 Это Y координата окна.
16 2 width 0xc8 Ширина окна.
18 2 height 0x66 Высота окна.
20 2 border 0x0000 Ширина рамки окна.
22 2 class 0x0001 1 это окно InputOutput. Есть и InputOnly, но они слишком специфические (да и не окна по сути) и их не будем рассматривать здесь.
24 4 visual 0x00000000 0 значит скопировать из родителя. Visual это какое-то абстрактное представление экрана в котором я так и не разобрался. Но CopyFromParent работает всегда. 😉
28 4 value_mask 0x00000000 Здесь кончается фиксированная часть запроса. (длиной в 8 двойных словах). Если нужно, можно задать дополнительные параметры окна. Для этого нужно в value_mask поставить единицы в некоторые биты, поставить необходимые параметры после 32го байта запроса и соответственно увеличить длины запроса в поле length на нужное число двойных слов.

И так, итоговый запрос который отправляем на сокет: 01 00 08 00 78 65 43 21 f0 de bc 9a 64 65 c8 66 00 00 01 00 00 00 00 00 00 00 00 00

Вот и полное описание запроса в приложении протокола:

 1 1 opcode 1 CARD8 depth 2 8+n request length 4 WINDOW wid 4 WINDOW parent 2 INT16 x 2 INT16 y 2 CARD16 width 2 CARD16 height 2 CARD16 border-width 2 class 0 CopyFromParent 1 InputOutput 2 InputOnly 4 VISUALID visual 0 CopyFromParent 4 BITMASK value-mask (has n bits set to 1) #x00000001 background-pixmap #x00000002 background-pixel #x00000004 border-pixmap #x00000008 border-pixel #x00000010 bit-gravity #x00000020 win-gravity #x00000040 backing-store #x00000080 backing-planes #x00000100 backing-pixel #x00000200 override-redirect #x00000400 save-under #x00000800 event-mask #x00001000 do-not-propagate-mask #x00002000 colormap #x00004000 cursor 4n LISTofVALUE value-list VALUEs 4 PIXMAP background-pixmap 0 None 1 ParentRelative 4 CARD32 background-pixel 4 PIXMAP border-pixmap 0 CopyFromParent 4 CARD32 border-pixel 1 BITGRAVITY bit-gravity 1 WINGRAVITY win-gravity 1 backing-store 0 NotUseful 1 WhenMapped 2 Always 4 CARD32 backing-planes 4 CARD32 backing-pixel 1 BOOL override-redirect 1 BOOL save-under 4 SETofEVENT event-mask 4 SETofDEVICEEVENT do-not-propagate-mask 4 COLORMAP colormap 0 CopyFromParent 4 CURSOR cursor 0 None

Немножко сложнее, но надеюсь более-менее понятно… Сложность здесь из-за того, что в запросе можно передать кучу параметров окна разного вида и формата. Но по сути все идет последовательно и более-менее логично.

После получения этого запроса, сервер создает окно с заданными параметрами. Но это окно не появится, так как все еще не показано на экране. Делаем это через запрос «MapWindow». На фоне прежнего, он совсем простенький:

Смещение Длина Имя поля Значение Заметки
0 1 opcode 0x08 Операция MapWindow == 8
1 1 0x00 Не используется
2 2 length 0x0002 Длина 8 байт.
4 4 wid 0x12345678 Это ID нашего окна.

На сокет уходит: 08 00 02 00 78 56 34 12 а окно становится видным.

Ответы

Сервер тоже присылает нам по сокету информацию. Она бывает 3 вида: Ответы (Reply), События (Events) и Ошибки (Errors).

Все три вида имеют длину минимум 32 байта. (А события и ошибки всегда точно 32 байта). Так что чтение из сервера происходит всегда порциями в 32 байта и если это Reply из тела ответа берем длину дополнительной части и читаем ее тоже.

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

  1. Ответы на запросы (Reply). Если запрос предполагает ответ от сервера, то сервер его присылает по сокету, как только обработает запрос. Если ответ содержит информацию, которая помещается в 32 байта, то это все что нужно принять. Если ответ длиннее, то в его теле содержится длина дополнительной части ответа.

Общий формат ответа такой:

Смещение Длина Имя поля Значение Заметки
0 1 code 1 1 == Reply
1 1 ? ? Или не используется или используется для какой-то часть ответа, длиной в 1 байт.
2 2 sequence s Это номер запроса, на котором ответ.
4 4 length n Длина ответа сверх первых 32 байта в двойных словах. Если не 0, то надо прочитать с сокета еще 4*n байта, чтобы взять весь ответ.
  1. События (Events). Содержат те же 32 байта и генерируются в ответ на какие-то события в GUI. Чтобы получать некоторые события, клиент должен подписаться на них, когда создает окно, например.

Некоторые события общесистемного характера присылаются всегда и всем.

Формат событии такой:

Смещение Длина Имя поля Значение Заметки
0 1 code 2..127 [+128] > 1 для событий. Если событие прислано от другого клиента через SendEvent, то к номеру события прибавляется 128. (Старший бит устанавливается в 1).
1 1 detail ? Деталь о событии если помещается в 1 байт.
2 2 sequence ? Номер запроса, после которого случилось событие.
4 4 timestamp time Время возникновения события
8 24 ? Зависят от события.
  1. Ошибки. Присылаются если какой-то запрос клиента нельзя было исполнить потому что содержит какую-то ошибку в данных или параметрах. Формат ошибки такой:
Смещение Длина Имя поля Значение Заметки
0 1 code 0 0 == Error
1 1 error code 1..255 Код ошибки.
2 2 sequence ? Номер ошибочного запроса.
4 28 data ? Подробности об ошибке. Зависит от кода ошибки.

Подключение.

А сейчас сделаем шаг назад и рассмотрим наверное самое сложное в X11 – подключение к серверу. К сожалению процедура сложная и запутанная и является камнем преткновения для прямого использования X11.

Именно подключение поднимает уровень вхождения в технологию.

Как мы увидели само использование протокола достаточно просто. Но подключение – это что-то с чем-то!

Само подключение по сути простое – создаем сокет и выполняем connect на него. Но сперва надо узнать адрес сервера. Для этого есть алгоритм:

Смотрим на содержание переменной окружения DISPLAY . Если существует, она содержит адрес X11 сервера в формате: [host]:D.S .

host – это хост сервера. Это может быть имя домейна, может быть строкой «/unix» или просто отсутствовать. Отсутствующий host равен «/unix» и означает что сервер слушает на unix domain сокете на локальной машине.

Кстати, это самый частый случай. Если host присутствует, это значит что подключаться надо к этому хосту, по TCP, через IP6 адрес.

D это номер дисплея, а S это номер экрана. В большинстве случаев на современных конфигурациях номер экрана будет 0, даже если мониторов больше одного. Все они виртуально объединены в один экран.

От номера дисплея зависит порт подключения к серверу. Если по TCP, то сервер слушает на порт 6000+D. Если подключаемся через unix domain сокет, он находится по адресу /tmp/.X11-unix/X – то есть, нулевой дисплей на /tmp/.X11-unix/X0 , первый на /tmp/.X11-unix/X1 и т.д.

И вот, мы подключились к сокету. После подключения, нельзя просто так посылать запросы. Надо сперва отправить на сервер информацию о себе и авторизоваться на сервере.

Все это содержится в первом (а точнее нулевом) запросе, который нестандартный и содержит:

Смещение Длина Имя поля Значение Заметки
0 1 byte_order «B» или «l» B (0x42) означает BIG-ENDIAN, a «l»(0x6c) – little-endian.
1 1 0x00 Не используется
2 2 major_ver 11 Мажорная версия протокола
4 2 minor_ver 0 Минорная версия протокола
6 2 auth_proto_len n Длина имя протокола авторизации
8 2 auth_data_len d Длина данных авторизации
10 2 not_used ? Выравнивание
12 n auth_proto string Протокол авторизации
12+n pad(n) Выравнивание к двойному слову.
12+n+pad(n) d auth_data string Данные авторизации
12+n+pad(n)+d pad(d) Выравнивание к двойному слову.

Первый байт определяет в каком формате наша программа понимает числа. Сервер будет присылать нам все числа длиннее одного байта в этом формате и будет понимать числа которые мы присылаем в этом формате.

Потом следует минимальная версия протокола, которая подошла бы программе. Если сервер поддерживает версию ниже этой, то подключение будет отклонено.

Потом следует имя протокола авторизации и собственно данные авторизации. Это типа доказательство, что эта программа имеет право подключаться к серверу X11.

Откуда берем имя протокола и данные об авторизации? Они находятся в файле, путь к которому находится в переменной окружения $XAUTHORITY . Если эта переменная не существует можно поискать в файле $HOME/.Xauthority – это самый распространенный вариант. Если у вашего приложения нет прав доступа к этому файлу или файл не существует, то значит у вас нет доступа к этому X11 серверу.

Файл бинарный и его формат не слишком хорошо задокументирован. Мне пришлось спрашивать на stackoverflow чтобы разобраться, да и то получилось лишь частично.

Так, структура файла, это последовательность записей вот таких структур:

typedef struct xauth < unsigned short family; unsigned short address_length; char *address; unsigned short number_length; char *number; unsigned short name_length; char *name; unsigned short data_length; char *data; >Xauth;

Но во первых, в файле, конечно указателей нет. Все строки вписаны просто последовательно, символ за символом в файле. Во вторых – все двухбайтовые числа всегда являются big-endian. Вне зависимости от архитектуры компьютера.

address – это HOST адрес сервера.

number – это номер дисплея, который мы уже определили из переменной $DISPLAY, записанный в виде текстовой строки!

name – это имя протокола. В настоящем времени и насколько я знаю, используется только MIT-MAGIC-COOKIE-1 протокол.

data – это массив байтов, примерно вот такой: 07 bd 70 26 1а ab 4c 7c 35 3c c1 b2 cc 25 a2 29 . который мы должны переслать серверу в знак, что у нас доступ позволен.

Перебираем этот файл пока не найдем запись, у которой HOST совпадает с хостом из $DISPLAY и номер дисплея с номером дисплея из $DISPLAY. Из этой записи достаем имя протокола и данные авторизации.

И так мы собрали все необходимые данные о нулевом запросе и формируем его:

Смещение Длина Имя поля Байты Пояснение
0 1 byte_order 0x6c l
1 1 0x00
2 2 major_ver 0x0b 0x00 0x000b
4 2 minor_ver 0x00 0x00 0x0000
6 2 auth_proto_len 0x12 length(«MIT-MAGIC-COOKIE-1») = 18
8 2 auth_data_len 0x10 length(cookie) = 16
10 2 0x00 0x00 не используется. Просто выравнивает.
12 18 auth_proto 4d 49 54 2d 4d 41 47 49 43 2d 43 4f 4f 4b 49 45 2d 31 «MIT-MAGIC-COOKIE-1»
30 2 pad(0x12) 0x00 0x00 Выравниваем до 20.
32 16 auth_data 07 bd 70 26 1а ab 4c 7c 35 3c c1 b2 cc 25 a2 29

К серверу уходит: 6c 00 0b 00 00 00 12 00 10 00 00 00 4d 49 54 2d 4d 41 47 49 43 2d 43 4f 4f 4b 49 45 2d 31 00 00 07 bd 70 26 1а ab 4c 7c 35 3c c1 b2 cc 25 a2 29 – всего 48 байтов.

На что сервер может ответить тремя возможными ответами. Вариант ответа определяется по первому байту. Он может быть:

0: Подключение отклонено. Весь ответ содержит:

Смещение Длина Имя поля Байты Пояснение
0 1 reply 0x00 Failed
1 1 n n Длина текстового ответа.
2 2 major_ver 0x0b 0x00 Мажорная версия протокола.
4 2 minor_ver 0x00 0x00 Минорная версия протокола.
6 2 data_len (n+p)/4 Длина дополнительной информации в двойных словах.
8 n data Какое-то текстовое сообщение об ошибке.
8+n p pad(n) Выравнивание до двойного слова.

2: Нужна дополнительная аутентификация. Я этого варианта не изучал потому что так и не успел найти систему, которая так бы отвечала…

1: Подключение принято.

Самый хороший для нас вариант. Ответ очень длинный и сложный, содержит главные параметры системы, которые мы должны запомнить и использовать позже в наших запросах.

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

 1 1 Success 1 unused 2 CARD16 protocol-major-version 2 CARD16 protocol-minor-version 2 8+2n+(v+p+m)/4 length in 4-byte units of "additional data" 4 CARD32 release-number 4 CARD32 resource-id-base 4 CARD32 resource-id-mask 4 CARD32 motion-buffer-size 2 v length of vendor 2 CARD16 maximum-request-length 1 CARD8 number of SCREENs in roots 1 n number for FORMATs in pixmap-formats 1 image-byte-order 0 LSBFirst 1 MSBFirst 1 bitmap-format-bit-order 0 LeastSignificant 1 MostSignificant 1 CARD8 bitmap-format-scanline-unit 1 CARD8 bitmap-format-scanline-pad 1 KEYCODE min-keycode 1 KEYCODE max-keycode 4 unused v STRING8 vendor p unused, p=pad(v) 8n LISTofFORMAT pixmap-formats m LISTofSCREEN roots (m is always a multiple of 4) FORMAT 1 CARD8 depth 1 CARD8 bits-per-pixel 1 CARD8 scanline-pad 5 unused SCREEN 4 WINDOW root 4 COLORMAP default-colormap 4 CARD32 white-pixel 4 CARD32 black-pixel 4 SETofEVENT current-input-masks 2 CARD16 width-in-pixels 2 CARD16 height-in-pixels 2 CARD16 width-in-millimeters 2 CARD16 height-in-millimeters 2 CARD16 min-installed-maps 2 CARD16 max-installed-maps 4 VISUALID root-visual 1 backing-stores 0 Never 1 WhenMapped 2 Always 1 BOOL save-unders 1 CARD8 root-depth 1 CARD8 number of DEPTHs in allowed-depths n LISTofDEPTH allowed-depths (n is always a multiple of 4) DEPTH 1 CARD8 depth 1 unused 2 n number of VISUALTYPES in visuals 4 unused 24n LISTofVISUALTYPE visuals VISUALTYPE 4 VISUALID visual-id 1 class 0 StaticGray 1 GrayScale 2 StaticColor 3 PseudoColor 4 TrueColor 5 DirectColor 1 CARD8 bits-per-rgb-value 2 CARD16 colormap-entries 4 CARD32 red-mask 4 CARD32 green-mask 4 CARD32 blue-mask 4 unused 

Но как бы и сложным это не выглядело бы, всю информацию не надо запоминать или даже анализировать.

Мы от этого ответа возьмем только то, что важно для нас. И это во первых два числа из полей: resource-id-base и resource-id-mask . Они дают нам диапазон в котором надо генерировать ID константы для всех объектов GUI. (Не забывайте, что в X11 все идентификаторы объектов генерируются на стороне клиента, а серверу именно клиент говорит какой будет ID окна или других объектов.)

Так, у сервера есть только одно ограничение – каждой программе он выделяет диапазон в котором идентификаторы должны помещаться. Так идентификатор должен содержать только те биты которые в resource-id-mask установлены в единицу. И идентификатор должен начинать с resource-id_base.

Еще надо запомнить для будущего использования диапазон клавиатурных кодов (min-keycode/max-keycode), найти в ответе те форматы изображений, которые программа может использовать и которые ей удобны.

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

Все остальное более или менее можно проигнорировать.

Я обычно ищу во всем этом многообразии тот SCREEN, который меня устраивает (32 бит TrueColor) и использую только его. А если сервер такое не поддерживает, просто заканчиваю работу. Это сильно упрощает работу и код.

Заключение

Ну это все для первого раза. Надеюсь сумел все объяснить яснее чем в документации и дать то понимание, которое позволит дальше свободно читать документацию (А она и правда хороша, если человек умеет ее понимать).

В качестве упражнения предлагаю конкурс-челендж: Написать программу на bash которая устанавливает соединение с X сервером и создает и показывает окно с заголовком «X11 rules».

Если никто не справится или не захочет, я попробую написать ее в качестве примера для следующей статьи цикла.

Спрашивайте в комментариях если что не ясно. Если что не нравиться тоже пишите. Статья может и будет редактироваться по мере обсуждения.

X11 linux что это

Большинство нынешних дистрибутивов по умолчанию устанавливают для пользователя графическую среду X11 (X11 Windows System), под управлением которой и выполняются все графические приложения. Как «внутри» устроена X11? Прежде всего, X11 – это распределенная модульная среда, состоящая из двух основных компонентов: X-сервера и X-клиента.

19.1. Клиент-серверная архитектура X11

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

В современных дистрибутивах как правило используется открытый свободно распространяемый X-сервер называющийся Xorg. Его конфигурационный файл называется xorg.conf и расположен в каталоге /etc/X11 . В конфигурационном файле описываются все устройства ввода, которые будет использовать X-сервер, настройки клавиатуры, драйвер видеокарты и многое другое. Более подробную информацию можно получить из справочного руководства ( man Xorg , man xorg.conf ).

X-клиент – это собственно пользовательская программа – браузер, почтовый клиент, видеоплеер, клиент мгновенных сообщений, игры, графические редакторы и просмотрщики и т.д.

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

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

Обрамление окон, иконки рабочего стола, панели и кнопки – это все отрисовывается X-клиентами. Рассмотрим пример окна некоторого приложения (в нашем случае файлового менеджера Nautilus из состава среды GNOME):

На этой картинке на самом деле показан результат работы двух X-клиентов: собственно файлового менеджера nautilus (именно он управляет отрисовкой меню, строки статуса, панелей, иконок и так далее). Второй X-клиент – менеджер окон (window manager) под названием metacity нарисовал рамку окна и кнопки на этой рамке. При этом горячие клавиши для закрытия окна, сворачивания, перемещения и других операций с окном отрабатывает именно metacity, а горячие клавиши копирования файла, перехода по каталогам, навигации по меню, подсвечивание иконок и тому подобное отрабатывает уже сам nautilus.

19.2. Графическая среда пользователя

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

  1. Все программы данного графического окружения используют одну и ту же библиотеку для отрисовки своих элементов управления
  2. В графическое окружение включается какой-либо менеджер окон
  3. Все программы для данного окружения разрабатываются с соблюдением определенных общих требований
  4. В состав окружение включаются самостоятельные программы для выполнения базовых функций – текстовые и табличные процессоры, графический редактор, браузер, IM-клиент и другие
  5. В состав окружения включаются служебные программы, предоставляющие пользователю возможность вызова других программ – например, приложение которое отрисовывает панель, на которой размещается кнопка для вызова меню со списком установленных программ и список окон
  6. В состав окружения включают утилиты для настройки оборудования и дополнительных функций

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

Наиболее распространенные графические среды в Linux – это GNOME и KDE. И та и другая среда имеют свою библиотеку для отрисовки элементов управления внутри окна (для GNOME это GTK, для KDE это Qt), включают в свой состав почтовый клиент, браузер, мультимедиа-проигрыватель, клиент мгновенных сообщений и графический редактор, файловый менеджер (он же по совместительству отрисовывает иконки на рабочем стол и отвечает за фон рабочего стола), программу которая отрисовывает боковые панели и набор маленьких программ-апплетов, которые встраиваются при необходимости в панели, игры, программы управления для настройки окружения и менеджер окон.

Некоторые X-клиенты не входят в состав какого-либо окружения – например, браузеры Firefox и Opera, медиапроигрыватель Mplayer, офисный пакет OpenOffice.Org. Самое главное что следует запомнить – что графическое окружение, или графическая среда – это всего лишь набор программ, а не одна большая программа вида «все-в-одном», и вы можете, работая в основном в одном окружении, абсолютно спокойно использовать программы другого.

19.3. Внутри X11. Упрощенная схема

X11 – система многослойная, но внутренне логичная и понятная. Схематически ее можно изобразить следующим образом:

Когда приложение отрисовывает что-либо, оно обращается к своей базовой библиотеке, она в свою очередь переадресовывает вызов (или уже цепочку вызовов) в библиотеку libX11, которая использую X11 Core Protocol передает команды на X-сервер. X-сервер интерпретирует команды и передает их на отрисовку драйверам устройств вывода. Воздействие же пользователя на устройства ввода считываются X-сервером через драйвера устройств ввода, через X11 Core Protocol передаются X-клиенту, libX11 переводит команды протокола в события и передает события в тулкит, и уже тулкит передает события программе для того чтобы та на них отреагировала.

То как приложение выглядит – то есть внешний вид строк ввода, полос скроллинга, панелей и кнопок – за все это отвечает библиотека-тулкит (toolkit). Два наиболее распространенных на сегодняшний день тулкита, Qt и GTK, примерно равны по возможностям – они обеспечивают достаточную переносимость приложений (есть реализации GTK и Qt для основных платформ), поддержку «тем» внешнего вида, предоставляют программисту объектно-ориентированный интерфейс и некоторый набор служебных функций и возможностей.

Базовая библиотека X11 (libX11, или Xlib) позволяет программе абстрагироваться и «не связываться» с низкоуровневыми функциями протокола X11, и таким образом обеспечивает сетевую прозрачность X11, то есть позволяет программам работать как с локальным X-сервером, так и с запущеным на другом компьютере, причем делается это незаметно для программы.

19.4. Внутри X11. Растровые шрифты и их отображение

С момента разработки в среде X11 отображение шрифтов управлял X-сервер. Приложение, когда ему необходимо вывести некоторый текст, просто инструктировало X-сервер «отобрази вот этот текст вот таким шрифтом в указанном месте». В ответ на это X-сервер выбирал из своей базы шрифтов наиболее подходящий, и использовал его для выполнения инструкций клиента, причем изначально эти шрифты были растровыми, то есть фактически содержали наборы заранее отрисованых глифов (символов).

Эта технология, называемая X Core Fonts, поддерживается в X11 и сейчас, поэтому в наборе пакетов любого дистрибутива всегда можно встретить наборы широко распространенных семейств растровых шрифтов – fixed, hevetica, times, courier. При этом каждый шрифт представляется множеством файлов, для различных сочетаний размера, ширины и начертания – например, если шрифт имеет десять вариантов размеров (от 8 до 18), две ширины (обычный и жирный) и два начертания (стандартное и курсив), то он будет представляться 40 файлами – по одному файлу для каждого из сочетаний размера, начертания и ширины.

Поскольку количество файлов получается очень большим, чтобы не устанавливать все эти шрифты на все компьютеры где запущены X-серверы, в систему X11 был введен такой объект как сервер шрифтов (font server). Системный администратор может настроить и запустить один сервер шрифтов для всей локальной сети, и указать X-серверу при запуске использовать шрифты с соответствующего сервера, что позволяет поддерживать на всех серверах один и тот же набор шрифтов с минимальными усилиями и избежать ситуации когда шрифт есть на одном компьютере, но его нет на другом.

В большинстве дистрибутивов Linux сервер шрифтов включен в поставку X11 по умолчанию, и называется xfs. Его конфигурационный файл как правило находится в каталоге /etc/X11/fs . В конфигурационном файле сервера шрифтов перечисляются каталоги с растровыми шрифтами, а в конфигурационном файле X-сервера указано, что основным источником шрифтов является сервер шрифтов,запущеный на этом же компьютере.

В новейшей версии проекта Xorg сервер шрифтов уже считается «устаревшей» технологией и по умолчанию не используется (хотя и входит в поставку). При необходимости его (сервер шрифтов) можно запустить и использовать.

Методика наличия предопределенных растеризованых глифов в шрифте позволяла добиться достаточно качественного отображения шрифта в большинстве случаев, но в то же время такие эта методика имеет определенные недостатки – как известно, растровые шрифты очень плохо «вращаются» на угол не кратный 90 градусам, и плохо масштабируются, а с появлением устройств высокой четкости (LCD-мониторов) возникла необходимость еще и отрисовывать шрифты в «сглаженном» виде, с мягкими переходами цвета, чего растровые шрифты также предоставить не могли.

Наиболее распространенное приложение, использующее методику X Core Fonts – это графический эмулятор терминала xterm, который есть в составе всех дистрибутивов, или простейший менеджер графического входа в систему XDM.

19.5. Внутри X11. FreeType и XFT

Для устранения этого недостатка растровых шрифтов была разработана специальные библиотеки XFT и FreeType, которые обеспечивают отображение векторных шрифтов и реализацию таких возможностей как сглаживание шрифтов, их поворот на произвольный угол и хинтинг (подгонку символов шрифта друг к другу оптимальным для данного шрифта способом). Поскольку данная методика плохо согласовывалась с уже сложившейся шрифтовой архитектурой X11, отображение векторных шрифтов было возложено на X-клиента.

При этом схема отображения шрифта меняется: X-клиент не передает на X-сервер запрос на вывод текста указанным шрифтом, а самостоятельно отрисовывает необходимы глифы шрифта использую функции FreeType и XFT, и передает на X-сервер уже сформированную картинку, которую X-сервер и отображает. Вполне логично, что при использовании этой методики X-клиент должен иметь доступ к оригиналу векторного шрифта (обычно это файл) – поэтому современные дистрибутивы также содержат еще и наборы векторных шрифтов PostScript и TrueType.

Новые версии тулкитов GTK и QT используют именно эту методику, но поскольку существуют еще и устаревшие тулкиты, такие как Motif или Xview (OpenLook) и значительное количество приложений на них основанных, да и с точки зрения необходимой полосы пропускания сети технология поддержки растровых шрифтов имеет явное преимущество пред XFT и FreeType, поддержка технологии растровых шрифтов по-прежнему входит в X11 и будет оставаться в ней еще долго.

19.6. Внутри X11. Расширения

Протокол X11 не является замершим в своем развитии, но его развития ведется не путем изменения самого протокола, а путем внесения в протокол расширений – то есть дополнительных опциональных наборов команд и инструкций. Например, для поддержки непрямоугольных окон было введено расширение XShape, для поддержки проигрывания видеороликов введено расширение XVideo, для поддержки OpenGL было введено расширение GLX и так далее.

19.7. Внутри X11. Полезные утилиты

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

xterm – эмулятор терминала

xfontsel – интерактивный просмотр растровых шрифтов

xdpyinfo – вывод информации о ваших настройках среды X11 и задействованных расширениях

xwininfo – просмотр информации об указанном окне (положение, размер, класс окна и т.п.)

xwd – моментальный «снимок» окна

xwud – показ результатов работы xwd

xhost – управление контролем доступа X-клиентов к X-серверу

19.8. Внутри X11. Менеджер окон

Существует особая разновидность X-клиентов, называемых менеджерами окон. Их основная функция – обеспечивать управление другими окнами – перемещением, изменением размеров, сворачиванием и разворачиванием окон, отрисовкой обрамлений окон, управление передачей фокуса от окна к окну а также управление Z-порядком размещения окон. Соответственно, в один момент времени для одного экрана может быть использован только один менеджер окон.

GNOME и KDE имеют свои собственные менеджеры окон – это metacity и kwin. Менеджеры окон являются взаимозаменяемыми – то есть вы можете выбрать и использовать тот из них, который вам больше нравится или кажется более удобным. Еще один распространенный (то есть наличествующий почти на всех UNIX-системах) менеджер окон – это twm. Крайне простой и примитивный, он тем не менее предоставляет пользователю базовые функции управления окнами и доступ к меню приложений.

Не следует путать или отождествлять графическую среду и менеджер окон – в большинстве графических сред для Linux менеджер окон является заменяемым по желании пользователя компонентом, в отличие от Windows или MacOS, в которых менеджер окон фактически монолитно склеен с остальными частями графической подсистемы.

19.9. Внутри X11. Composite, XGL и Compiz

Современные версии X-сервера Xorg поддерживают специфическое расширение, называемое Composite. Вкратце его назначение описывается следующим образом: в процессе прорисовки вывода X-клиента, X-сервер рисует не непосредственно в видеопамять (то есть не на экран), а в промежуточный внеэкранный буфер (off-screen buffer), а специализированная программа, называемая Composite manager, подключается к этому буферу, при необходимости изменяет изображение и выводит в видеопамять уже измененное изображение. Такая технология позволяет получить эффекты прозрачности, искажения, плавного «всплытия» окон и многие другие без внесения каких-либо изменений в код X-клиентов или X-сервера. С другой стороны, преобразования изображений лучше реализовывать с использованием аппаратного ускорения, предоставляемого видеокартой.

XGL – это одновременно X-сервер и X-клиент. Как и обыкновенный X-сервер, XGL позволяет подключаться к себе X-клиентам, отсылает им события от устройств ввода и принимает от них команды отрисовки, отрисовку же принятых команд XGL производит с помощью OpenGL. Кроме того, как X-сервер XGL реализует поддержку расширения Composite. Как следствие, пользователь получает следующий «слоеный пирог»: внутри реального X-сервера, от которого требуется только поддержка OpenGL, запускается XGL. Все остальные программы Window manager, Composite manager и обычные X-клиенты подключаются к XGL. Поскольку назвать «элегантной» такую многоуровневую конструкцию нельзя, функции XGL были перенесены в основной X-сервер, а в интерфейс драйверов видеокарт была заложена возможность поддержки расширения Composite.

Наиболее развитые на данные момент драйверы имеют видеокарты NVidia, ATI и Intel. Драйверы видеокарт Intel пишутся сообществом разработчиков Xorg, по открытым фирмой-производителем спецификациям, и поэтому поддерживают Composite и аппаратное ускорение прорисовки трехмерной и двумерной графики, поэтому владельцы этих карт могут использовать Composite manager и расширение Composite в сочетании с поддержкой OpenGL. Спецификации на видеокарты фирм ATI и NVidia закрыты (недоступны разработчикам Xorg), и поэтому открытые драйвера отличаются усеченной функциональностью и слабой поддержкой аппаратного ускорения. Закрытые («проприетарные») драйверы видеокарт NVidia, предоставляемые производителем, обеспечивают поддержку аппаратного ускорения при выводе двумерной и трехмерной графики и предоставляют поддержку Composite. Драйверы для новейших видеокарт ATI следует признать крайне некачественными – в настоящий момент далеко не во всех версиях этих драйверов возможно одновременно задействовать аппаратную поддержку OpenGL и поддержку Composite.

Поддержка функции GLX_texture_from_pixmap была реализована в проприетарных драйверах видеокарт ATI версии 8.42, но эти драйвера этой и более новой версий поддерживают не весь спектр видеокарт производства этой фирмы.

Compiz – это Composite manager, которые в процессе работы использует библиотеки OpenGL и аппаратное ускорение, предоставляемое видеоадаптером. Сопоставляя вышесказанное о драйверах для различных видеокарт, можно сделать вывод что владельцы видеокарт NVidia и Intel могут использовать восзможности и эффекты, реализованные в Compiz, без сколь-нибудь трудностей, а владельцам видеокарт ATI не поддерживаемых новыми версиями драйверов, если они хотят использовать Compiz, необходимо прибегнуть в многоуровневой архитектуре с XGL.

В начало → Linux не для идиотов → X11 и все-все-все

Использование X11 — 1. Введение

X Window System, версия 11 (или сокращенно X11) является системой графического отображения с прозрачной для сети архитектурой клиент-сервер. Она позволяет приложениям графически создавать на экране пиксели, линии, тексты, изображения и т.п. X11 также имеет дополнительные библиотеки, благодаря которым приложения могут свободно рисовать интерфейсы пользователя — кнопки, поля для текста и т.п.

X11 фактически является стандартной системой графического отображения в мире Unix. Она поставляется вместе с Linux, *BSD и большинством коммерческих вариантов Unix. На ее основе работают такие виды среды рабочего стола, как CDE, KDE и GNOME.

1.2 Что такое Mac OS X?

Mac OS X — операционная система, производителем которой является Apple. Как и предшествующие NeXTStep и OpenStep, она основана на BSD и таким образом входит в семейство операционных систем Unix. Но при этом она выпускается с системой графического отображения, являющейся частной собственностью. Графический процессор называется Quartz, а интерфейс Aqua, хотя оба названия часто используются как взаимозаменяемые.

1.3 Что такое Darwin?

Darwin по сути является упрощенной версией Mac OS X, которую можно получить бесплатно с полным исходным кодом. Она не содержит Quartz, Aqua и прочую сопутствующую технологию. По умолчанию она предлагает только текстовую консоль.

1.4 Что такое XFree86?

XFree86 — реализация X11 на основе исходного кода. Первоначально она была разработана для применения на ПК Intel x86, отсюда и ее название. В настоящее время применяется во многих архитектурах и операционных системах, в т.ч. OS/2, Darwin, Mac OS X и Windows.

1.5 Что такое Xtools?

Xtools — продукт Tenon Intersystems. Это версия X11 для Mac OS X, основанная на XFree86.

1.6 Клиент и сервер

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

X11 позволяет серверу и клиентам находиться на разных машинах, в результате чего часто происходит путаница в терминах. В среде с рабочими станциями и серверами вы будете использовать сервер отображения X11 на машине рабочей станции, а приложения (клиенты X) — на машине сервера. Таким образом, говоря «сервер», вы имеем в виду программу сервера отображения X11, а не машину, спрятанную в вашем шкафу.

1.7 Что означает «бескорневой» («rootless»)?

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

Теперь вернемся к нашей теме: Как и любая графическая среда, X11 написана для самостоятельной работы и полного управления экраном. В Mac OS X Quartz уже управляет экраном, т. обр. для одновременной работы обеих систем надо совершить определенные действия.

Одно из возможных действий — позволить системам работать поочередно. Каждая среда получает в распоряжение весь экран, но в определенный момент времени видна только одна из них и пользователь может перемещаться между ними. Это называется полноэкранным или корневым режимом. Корневым — потому что есть абсолютно нормальное корневое окно на экране X11, работающее также, как и в других системах.

Другое действие — комбинирование окон двух видов среды. Это устраняет необходимость перемещения между экранами, а также избавляет от корневого окна X11, т.к. Quartz уже берет на себя заботу о фоне рабочего стола. Поскольку нет корневого (видимого) окна, данный режим называется «бескорневым». Это наиболее удобный способ использования X11в Mac OS X.

1.8 Что такое менеджер окон?

В большинстве видов графической среды вид рамок окон (строка заголовка, кнопка закрытия и т.д.) определяется системой. В X11 это решается иначе. Рамки окон (также называемые «декоративными обрамлениями») в X11 обеспечиваются отдельной программой — менеджером окон. Во многих отношениях менеджер окон является просто еще одним клиентом; он запускается и общается с сервером X через те же каналы.

Существует большой выбор разных менеджеров окон. На сайте xwinman.org имеется исчерпывающий список. Наиболее популярные из них позволяют пользователю настроить вид через т. наз. темы. Многие менеджеры окон также обеспечивают такие дополнительные функции, как всплывающие меню в корневом окне, стыковки и кнопки запуска.

Для Fink скомпилированы многие менеджеры окон — см. текущий список.

1.9 Что такое Quartz/Aqua, Gnome и KDE?

Это виды среды рабочего стола, в числе многих других. Их цель — обеспечение дополнительных границ для приложений, чтобы их вид и поведение были визуально последовательными. Пример:

графический процессор : X11

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

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

Языки: | English | Français | Deutsch | 日本語 (Nihongo) | Русский (Russkiy) | Español | Português | 中文 (简) (Simplified Chinese) |
Последнее изменение: nieder ‚ 04 August 2023 , 05:08 GMT

Re: что такое x11?

X11 — графическая система для UNIX. А x1 xap1 xd1 xv1 — названия разделов дистрибутива (буквы означают категорию x — сама X11 xap — приложения для нее xv — вариант оконной системы из Solaris’a xd — исходники X’ов) цифры обозначают N диска (анахронизм). А вообще-то полезно документацию читать — помогает.

anonymous
( 28.01.00 20:57:46 MSK )

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

Похожие темы

  • Форум [blocks B ]
  • Форум ~X11 (2004)
  • Форум emerge xorg-x11 (2009)
  • Форум x11 forwarding (2012)
  • Форум Несколько X11 (2013)
  • Форум X11 port (2002)
  • Форум Мультитач в x11 (2014)
  • Форум Вопрос про /etc/X11/fs/config (2002)
  • Форум X11 сервер для Windows (2003)
  • Форум x11-libs/cario (2014)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *