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

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

Менеджер сети

Эта глава охватывает следующие темы:

Введение

Менеджер сети (Net) дает пользователям QNX прозрачное расширение мощных возможностей механизма передачи сообщений. Взаимодействуя непосредственно с Микроядром, Менеджер сети усиливает механизм IPC на основе обмена сообщениями, передавая сообщения на удаленные компьютеры. Кроме того, Менеджер сети обеспечивает:

Обязанности Менеджера сети

Менеджер сети отвечает за распространение примитивов передачи сообщений QNX в пределах локальной сети. Стандартные примитивы передачи сообщений используются без изменения для связи с удаленным компьютером. Другими словами, не существует особых "сетевых" Send(), Receive() или Reply().

Независимый модуль

Менеджер сети не должен быть обязательно встроен в образ операционной системы. Он может быть запущен и остановлен в любое время, чтобы обеспечить или удалить сетевые возможности передачи сообщений.

При запуске Менеджер сети регистрируется у Менеджера процессов и Ядра. Это активизирует код внутри последних, который взаимодействует с Менеджером сети. Это означает, что передача сообщений по сети и создание удаленных процессов - это не просто добавляемый поверх операционной системы слой. Сетевые возможности интегрированы в самую сердцевину примитивов передачи сообщений и управления процессами.

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

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

Интерфейс Микроядро/Менеджер сети

Микроядро и Менеджер процессов взаимодействуют с Менеджером сети через специальную неблокирующую очередь в памяти. Эта очередь представляет собой список передач, которые должен выполнить Менеджер сети. Элементы очереди содержат всю информацию о конкретной операции (например, Send(), Reply(), создание виртуального канала (VC), передача удаленного сигнала и т.д.).

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

Ниже приведены диаграммы, иллюстрирующие процесс посылки и приема удаленных сообщений.

Посылка сообщения на удаленный узел


fig: i/sendrmot.gif


Процесс вызывает Send() или Reply() к удаленному узлу.


В случае вызова Send() или Reply() к удаленному узлу, имеют место следующие события:

  1. Процесс вызывает Send() или Reply(), и Микроядро копирует данные из области данных процесса в буфер виртуального канала.
  2. Микроядро добавляет в очередь Менеджера сети элемент, содержащий идентификаторы отправителя, удаленного получателя и указатель на данные в буфере виртуального канала. Если перед этим очередь была пуста, то Менеджер сети получает прокси, извещающее о том, что появилась новая работа.
  3. Менеджер сети извлекает элемент из очереди.
  4. Менеджер сети посылает элемент соответствующему сетевому драйверу.
  5. Менеджер сети начинает передачу данных по сети и отвечает за доставку.

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

Получение сообщения с удаленного узла


fig: i/recvrmot.gif


Процесс получает удаленный Send() или Reply().


Допустим, что удаленный узел послал сообщение, как описано выше. В этом случае на принимающем узле имеют место следующие события:

  1. Сетевой драйвер помещает поступившие по сети данные в соответствующий буфер виртуального канала.
  2. Сетевой драйвер информирует Менеджер сети о том, что прием завершен.
  3. Менеджер сети использует частный вызов Ядра, извещая его о том, что прием завершен.
  4. Микроядро копирует данные из буфера виртуального канала в буфер процесса (при условии, что он RECEIVE- или REPLY-блокирован на этом виртуальном канале).

Любые управляющие пакеты, которые получает Менеджер сети, немедленно переправляются Менеджеру процессов через стандартный примитив Send(). Эти управляющие пакеты используются для распространения сигналов и создания виртуальных каналов.

Сетевые драйверы

Подобно Менеджеру файловой системы и Менеджеру устройств, Менеджер сети не содержит аппаратно-зависимого кода. Эта функциональность обеспечивается драйверами сетевых плат. Менеджер сети может поддерживать одновременно несколько сетевых драйверов. Каждый драйвер обычно обслуживает одну сетевую плату. Вы можете иметь драйверы/платы одного и того же типа или различных типов - например, два драйвера/платы Ethernet или, допустим, драйвер/плату Ethernet и драйвер/плату Arcnet.

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

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

Идентификаторы узла и сети

Каждый узел в локальной сети идентифицируется двумя числами:

Физический ID узла

Физический ID узла определяется оборудованием. Сетевые платы обмениваются данными друг с другом, указывая физический ID удаленного узла, с которым должна быть установлена связь. В случае сети Ethernet или Token Ring - это большое число, которым неудобно оперировать людям и утилитам. Например, каждая плата Ethernet или Token Ring имеет уникальный 48-битный физический ID узла в соответствии со стандартом IEEE 802. Платы Arcnet, напротив, имеют всего лишь 8-битный ID.

Использование физического ID узла имеет существенный недостаток: при соединении некоторых сетей может возникнуть конфликт адресов (особенно в случае Arcnet), или формат адресов может радикально отличаться.

Логический ID узла

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

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

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

Логические ID узлов обычно присваиваются по порядку, начиная с 1. Например, узел, имеющий плату Ethernet, может получить логический ID 2, который будет соответствовать физическому ID узла 00:00:c0:46:93:30.

Логические ID узлов должны быть уникальны для всех узлов во всех соединенных QNX-сетях, чтобы сделать возможным функционирование мостов.

Логический ID сети

ID сети идентифицирует конкретную логическую сеть. Логическая сеть - это любое оборудование, которое позволяет сетевому драйверу непосредственно взаимодействовать с сетевым драйвером на другом узле. Это может быть как просто последовательный порт, так и сложная сеть Ethernet с аппаратными мостами.

На следующей диаграмме узел 7 имеет две сетевые платы, которые позволяют ему иметь доступ к узлам в логических сетях 1 и 2. Узлы 8 и 9 имеют по три платы, подключающие их к сетям 1, 2 и 3.

Заметьте, что все логические ID узлов уникальны для всех трех логических узлов.


Note: Логические ID узлов сети назначаются системным администратором. Более подробно см. в главе "Установка сети" в книге Руководстве пользователя.


fig: i/multinet.gif


Несколько физических сетей сосуществуют посредством логических сетей.


Выбор сети

В случае, когда узлы соединены более чем одной логической сетью, Менеджер сети может выбирать, какую из сетей использовать для передачи к удаленному узлу. Например, на приведенном выше рисунке узел 7 может передавать данному узлу 8, используя либо сеть 1, либо сеть 2.

Распределение нагрузки

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

Например, два компьютера Pentium, соединенные сетью 10BASE-T Ethernet, будут ограничены 1.1 миллионом байт в секунду, то есть скоростью передачи данных, обеспечиваемой сетевым оборудованием. Однако если поместить по две платы Ethernet в каждый из компьютеров и соединить их отдельными кабелями, то Менеджер сети сможет передавать данные по обеим сетям одновременно. При большой нагрузке это обеспечит увеличение пропускной способности в два раза по сравнению с одной сетью.

Менеджер сети будет пытаться сбалансировать нагрузку, выбирая сетевой драйвер. В рассмотренном выше примере, если производится передача с узла 7 на узел 8 по сети 1 и другая передача на узел 8 инициируется на узле 7, то сеть 2 будет автоматически выбрана для передачи данных.

Отказоустойчивость

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

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

Мосты между сетями QNX

Менеджер сети позволяет любому узлу играть роль моста между двумя отдельными сетями QNX, базирующимися на стандарте IEEE 802.


Note: Так как QNX использует одинаковый формат пакетов и протокол на всех IEEE 802 сетях, можно создавать мосты между сетями Ethernet, Token Ring и FDDI.

Для сетей Arcnet нельзя создавать мосты.


Рассмотрим следующую диаграмму, где одной сети принадлежат узлы 17 и 18, а другой - узлы 18 и 19:


fig: i/relay.gif


Мост между двумя IEEE 802 QNX сетями.


Узлы 17 и 18 находятся в одной сети, поэтому они могут общаться друг с другом напрямую. То же справедливо для узлов 18 и 19. Но как могут общаться узлы 17 и 19?

Так как обе локальные сети базируются на IEEE 802, узел 18 автоматически перенаправляет пакеты, позволяя узлам 17 и 18 создать виртуальный канал. Хотя они и не подключены к одной и той же локальной сети, узлы 17 и 19, тем не менее, могут общаться друг с другом.

Сеть TCP/IP

Присущая QNX поддержка сети реализует локальную сеть на основе собственного частного протокола и оптимизирована для организации интерфейса между QNX компьютерами. Но для связи с не-QNX системами, QNX использует ставший промышленным стандартом набор протоколов, называемый TCP/IP.

По мере того как Интернет стал занимать все большее место в нашей повсеместной жизни, протокол, на котором он основан - IP (Internet Protocol) - приобретает все большее значение. Даже если вы не подключаетесь непосредственно к Интернет как к таковому, IP протокол и связанный с ним инструментарий поистине вездесущи, делая IP стандартом "де-факто" для многих частных сетей.

IP используется везде, начиная от простых задач (например, удаленный вход в систему (login)) и до более сложных (например, отслеживание биржевых котировок в реальном времени). Все больше и больше компаний используют World Wide Web ("всемирную паутину"), основанную на IP, для переписки с клиентами, рекламы и другой деловой активности.

Менеджер TCP/IP

Менеджер TCP/IP в QNX происходит из Berkley BSD 4.3, который является наиболее распространенным стеком TCP/IP в Интернет и использован как основа для многих систем.

Сокет API

Библиотека BSD сокета API была очевидным выбором для QNX 4. Сокет API является стандартным API для программирования TCP/IP в среде Unix. В среде Windows, Winsock API базируется на BSD сокете API. Это облегчает переход между ними.

Имеются все процедуры, которые могут понадобиться прикладным программистам:

accept()
bind()
bindresvport()
connect()
dn_comp()
dn_expand()
endprotoent()
endservent()
gethostbyaddr()
gethostbyname()
getpeername()
getprotobyname()
getprotobynumber()
getprotoent()
getservbyname()
getservent()
getsockname()
getsockopt()
herror()
hstrerror()
htonl()
htons()
h_errlist()
h_errno()
h_nerr()
inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
ioctl()
listen()
ntohl()
ntohs()
recv()
recvfrom()
res_init()
res_mkquery()
res_query()
res_querydomain()
res_search()
res_send()
select()
send()
sendto()
setprotoent()
setservent()
setsockopt()
shutdown()
socket()

Распространенные утилиты и демоны из Интернет могут быть легко перенесены или просто перекомпилированы в такой среде. Это облегчает использование имеющихся готовых наработок.

Возможность взаимодействия сетей

При разработке Менеджера TCP/IP в QNX в первую очередь принималась во внимание возможность взаимодействия сетей. Учитывались как требования RFC, так и реальные условия. Менеджер TCP/IP охватывает всю функциональность, предлагаемую RFC 1122. Также поддерживаются протоколы ARP, IP, ICMP, UDP и TCP.

NFS

Network File System (NFS) является приложением TCP/IP, реализованным на большинстве DOS и Unix систем. NFS позволяет отображать удаленные файловые системы - или их части - в локальное пространстве имен. Файлы на удаленной системе показываются как часть локальной файловой системы QNX.


Note: В QNX 4 для поддержки NFS требуется менеджер Socket. Учтите, что "облегченная" версия менеджера, Socklet, может быть использована, если нет необходимости в NFS.

SMB

Server Message Block (SMB), который используется многими различными серверами, такими как Windows NT, Windows 95, Windows for Workgroups, LAN Manager и Samba. SMBfsys позволяет клиенту QNX прозрачный доступ к удаленным дискам на таких серверах.

Оконная система Photon microGUI

Эта глава охватывает следующие темы:

Графическое микроядро

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

При создании оконной системы Photon microGUI была применена архитектура микроядра, успешно воплощенная в QNX для создания POSIX ОС для встроенных систем.

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

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

Микроядро Photon выполняется как маленький процесс (размер кода 45K), реализуя только несколько фундаментальных примитивов, которые внешние опциональные процессы используют для построения более высокого уровня функциональности оконной системы. По иронии, для самого микроядра Photon "окна" не существуют. Микроядро Photon не может также "рисовать" что-либо или управлять мышью либо клавиатурой.

Для управления средой GUI, Photon создает 3-мерное "пространство событий" и ограничивается только оперированием регионами и выполнением отсечения и направления различных событий по мере их прохождения сквозь регионы в этом пространстве событий.

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

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

Пространство событий Photon

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

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


fig: i/regions.gif


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


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

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

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

Регионы

Каждому региону соответствует прямоугольная область, определяющая его положение в 3-мерном пространстве событий. Регион также имеет атрибуты, определяющие, как он взаимодействует с различными классами событий при пересечении ими региона. Взаимодействие региона с событиями определяется двумя битовыми масками:

Маска чувствительности определяет, должен ли процесс-владелец региона оповещаться о пересечении региона тем или иным событием. Каждый бит маски чувствительности определяет, чувствителен ли регион к определенному типу событий. Когда событие пересекает регион, для которого установлен бит (равен 1), копия этого события помещается в очередь процесса-владельца региона, извещая приложение о прохождении события через регион. Такое извещение никак не изменяет само событие.

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

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

События

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

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

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

Список прямоугольников, прикрепленный к событию, может определять одну или более прямоугольных областей, либо "исходную точку" - единственный прямоугольник, у которого координаты верхнего левого и нижнего правого углов совпадают.

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

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

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

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


fig: i/clipping.gif


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


В том случае, если событие рисования целиком отсекается при пересечении с регионом, оно прекращает существование. Этот механизм "непрозрачных" окон, изменяющих список прямоугольников события рисования, обеспечивает правильное отсечение событий рисования по мере их продвижения от исходного региона (и связанного с ним процесса) к пользователю.

Графические драйверы

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

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

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

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

Несколько графических драйверов

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

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

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

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

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

Цветовая модель

Для представления цветов используется 24-битная RGB модель (по 8 бит для красного, зеленого и синего), что обеспечивает 16,777,216 цветов. В зависимости от используемого типа оборудования, драйвер либо непосредственно отображает 24-битный цвет, либо использует различные варианты смешивания цветов, чтобы отобразить требуемый цвет на оборудовании, поддерживающем меньшее число цветов.

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

Масштабируемые шрифты

В дополнение к поддержке растровых шрифтов, Photon также предлагает масштабируемые шрифты. Эти шрифты могут масштабироваться практически с любым размером точки и использовать технологию сглаживания (16 оттенков) для четкого и ясного отображения на экране с любым разрешением.

Масштабируемые шрифты в Photon поддерживаются быстродействующим сервером шрифтов, который загружает описания шрифтов, хранящиеся в сжатом виде в файлах *.pfr (Portable Font Resource, ресурсы переносимых шрифтов), и затем приводит вид символов в соответствие с любым размером точки и разрешением. Стоит отметить, что формат PFR обеспечивает более чем в два раза лучшее сжатие по сравнению с PostScript шрифтами.

Наборы шрифтов

Основной латинский набор

Основной латинский (Core Latin) набор шрифтов Photon (latin1.pfr), который охватывает два набора символов стандарта Unicode, Basic Latin (U+0000 - U+007F) и Latin-1 Supplement (U+0080 - U+00FF), включает следующие масштабируемые шрифты:

Расширенный латинский набор

Расширенный латинский (Extended Latin) набор (latinx.pfr) охватывает наборы символов Unicode Latin Extended-A (U+0100 - U+017F) и Latin Extended-B (U+0180 - U+0217) и включает следующие шрифты:

Поддерживаемые языки

Имея в своем распоряжении Основной латинский набор (latin1.pfr), разработчик может поддерживать множество языков, включая:

Датский;
Голландский;
Английский;
Финский;
Фламандский;
Французский;
Немецкий;
Гавайский;
Исландский;
Индонезийский;
Ирландский;
Итальянский;
Норвежский;
Португальский;
Испанский;
Суахили;
Шведский.

Расширенный набор (latinx.pfr) позволяет дополнительно поддерживать:

Африканский;
Баскский;
Каталонский;
Хорватский;
Чешский;
Эсперанто;
Эстонский;
Гренландский;
Венгерский;
Латышский;
Литовский;
Мальтийский;
Польский;
Румынский;
Словацкий;
Турецкий;
Валлийский.

Дополнительные языковые пакеты

Для Photon предлагаются несколько дополнительных пакетов для поддержки национальных языков:

Многоязычная поддержка Unicode

Photon разработан с учетом поддержки национальных символов. Следуя стандарту Unicode (ISO/IEC 10646), Photon предоставляет разработчикам возможность создавать приложения, поддерживающие основные мировые языки.

Unicode основывается на наборе символов ASCII, но использует 16-битную кодировку для полной поддержки многоязычного текста. Нет никакой необходимости прибегать к escape-последовательностям или управляющим кодам для задания любого символа любого языка. Заметьте, что кодировка Unicode обрабатывает все символы - алфавитные, идеограммы, специальные символы - абсолютно одинаковым образом.

UTF-8 кодировка

Известная раньше как UTF-2, UTF-8 (от "8-битная форма") кодировка определяет использование символов Unicode в 8-битной среде UNIX.

Вот некоторые основные характеристики UTF-8:

Системная библиотека включает ряд функций преобразования:
Функция:Описание:
mblen()Длина многобайтной строки в символах
mbtowc()Преобразовать многобайтный символ в двухбайтный символ
mbstowcs()Преобразовать многобайтную строку в двухбайтную строку
wctomb()Преобразовать двухбайтный символ в его многобайтное представление
wcstombs()Преобразовать строку двухбайтных символов в многобайтную строку

В дополнение к перечисленным выше функциям, разработчики могут также воспользоваться собственной библиотекой Photon, функциями PxTranslate, которые выполнят различные преобразования наборов символов в/из UTF-8.

Поддержка анимации

Photon обеспечивает немерцающую анимацию через специальный виджет-контейнер с "двойным буфером" (PtDBContainer), который создает специальный контекст в памяти для отрисовки изображений.

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

Поддержка печати

Photon предусматрив