SWD Software Ltd. - официальный дистрибьютор QNX на территории России и стран бывшего СССР Операционная система реального времени QNX
Инструменты для создания надёжных встраиваемых систем и
интеллектуальных устройств любой сложности
QNX Software Systems - разработчик встраиваемой операционной системы QNX
Информационные брошюры
Статьи и публикации
Обзоры
Операционные системы
Графические интерфейсы
Средства разработки
Прикладные системы на базе ОС QNX
Разное
Конкурсные статьи
Техническая литература
Материалы конференций QNX-Россия
Полезные ссылки
Блог QNX
Главная страница > Материалы > Статьи и публикации > Графические интерфейсы > Графическая оболочка Photon - революция в мире интерфейсов Сделать страницу стартовой Послать ссылку коллеге Версия для печати

Графическая оболочка Photon - революция в мире интерфейсов

Введение
Идеология
Регионы драйверов
Экран, распределенный по сети
Работа с удаленным экраном
Администратор оконного интерфейса
Фокусировка
Обработка событий
Разработка программ
Несколько практических аспектов
Литература

Когда, в 1982 году, на рынке технологий появилась ОС QNX - первая операционная система на базе микроядра, она тут же привлекла внимание всех специалистов, от производителей микроконтроллеров до проектировщиков распределенных систем управления, объединив в себе миниатюрность DOS, мощность UNIX и дополнив этот набор распределенной обработкой данных в реальном времени.

Со временем требования к системам растут. И cегодня, уже ни один пользователь не представляет себе работу без графического оконного интерфейса. Однако, разговор о графической среде навевает у разработчиков мысли о неисчислимых мегабайтах памяти, требуемых для X Window System или продуктов фирмы Microsoft. И QNX Software Systems Ltd. еще раз показала, что нет ничего невозможного, разработав графическую оконную систему на базе микроядра - Photon.

Думаю, что не найдется программиста, который не мечтал бы о графической среде, которая:

  • легко умещается в 300К памяти,
  • показывает высокую производительность даже на самой дешевой аппаратной платформе,
  • легко масштабируется для использования в разработках самого различного назначения,
  • способна отображать свои окна в среде MS Windows или X Window System,
  • имеет расширенные средства для проектирования приложений.

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

[ Наверх ]

Идеология

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

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

Photon1.gif - 10.0 K
Рис. 1

знакомый с оптикой на уровне средней школы. Для начала, представьте себе прозрачный параллелепипед. Пространство, которое он ограничивает, в терминах Фотона, называется - пространством событий. Грань параллелепипеда, обращенная к вам, является экраном компьютера (рис. 1). Т.е. вы находитесь на верху пространства событий. Противоположная грань представляет собой "корневую" плоскость. В этом пространстве размещаются объекты, которыми оперирует Фотон - регионы. Они представляют собой прямоугольные области, расположенные параллельно корневой плоскости и являются агентами QNX процессов в пространстве событий. С помощью регионов задача получает сведения о происходящем, и с их же помощью доставляет свою информацию.

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

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

Photon2.gif - 7.0 K
Рис. 2

Следующий регион, чувствительный к этому событию, будет получать уже новый набор прямоугольников. На рисунке 2 показано событие, полученное регионом Г после прохождения через регионы А, Б и В. Непрозрачность регионов, так же, позволяет избежать нежелательных эффектов прохождения событий. Допустим, что регион Б посылает событие отображения в направлении графического региона (говоря проще, окно Б пытается отобразить себя на экране). Так как регион В, расположенный перед регионом Б непрозрачен для событий Б, то он вырезает часть события таким образом, чтобы оно, не изменило область региона В на экране.

[ Наверх ]

Регионы драйверов

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

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

Обработку событий клавиатуры, мыши или touchscreen производит отельный драйвер, называемый Pointer.

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

Photon3.gif - 11.2 K
Рис. 3

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

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

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

[ Наверх ]

Экран, распределенный по сети

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

Photon4.gif - 7.4 K
Рис. 4

[ Наверх ]

Работа с удаленным экраном

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

[ Наверх ]

Администратор оконного интерфейса.

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

По внешнему виду и функциональным возможностям оконный интерфейс выполнен в стиле известного OSF Motif стандарта [1]. В Фотоне, как и в любой другой оболочке, пользователь получает возможность управления графическими окнами - перемещение, изменение размера, сворачивание в икону и т.д.

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

[ Наверх ]

Фокусировка

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

[ Наверх ]

Обработка событий

Как и X Window System, Фотон представляет архитектуру клиент - сервер. Сервером выступает ядро - Photon, обеспечивающее поддержку пространства событий. Любой другой процесс, будь то драйвер или программа пользователя представляет собой клиентскую часть. Интерфейс между клиентом и сервером базируется на механизме передачи сообщений, используемом в QNX.

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

  • запрос
  • синхронное оповещение
  • асинхронное оповещение

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

Пример 1

/* Размер буфера события */
#define EVENT_SIZE sizeof( PhEvent_t) +1000
void main( int argc; char *argv[])
{ PhEvent_t *event; /* Буфер событий */
........ while( 1) { ............ /* Код пользователя */
/* Запрос к Фотону с моментальным ответом */
switch( PhEventPeek( event, EVENT_SIZE))
{ case Ph_EVENT_MSG: /* Обработка события */
PtEventHandler( event);
break;
case -1:
/* Ошибка запроса */
perror( "PhEventPeek failed");
case 0:
/* Нет доступных событий */
break;
}
}
}

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

Пример 2
/* Размер буфера события */
#define EVENT_SIZE
sizeof( PhEvent_t) + 1000void main( int argc; char *argv[])
{ PhEvent_t *event; /* Буфер событий */ ........
while( 1) { ............ /* Код пользователя */
/* Запрос к Фотону с ожиданием ответа */
switch( PhEventNext( event, EVENT_SIZE))
{ case Ph_EVENT_MSG: /* Обработка события */
PtEventHandler( event);
break;
case -1:
/* Ошибка запроса */
perror( "PhEventNext failed");
break;
}
}
}

Если вам нужно больше гибкости, например, когда вы пишете программу - сервер, которая должна принимать и обрабатывать сообщения, приходящие от других задач, вам нужно использовать метод асинхронного оповещения. В этом случае программа вызывает функцию, устанавливающую proxy [3,8], которого Фотон будет "включать" после прихода события. Программа, выполняющая свои основные функции, как сервер, будет получать среди сообщений от клиентов, извещения от proxy о приходе события.

Пример 3
/* Размер буфера события */
#define EVENT_SIZE sizeof( PhEvent_t) +1000
void main( int argc; char *argv[])
{ pid_t pid;
/* Идентификатор процесса, посылающего сообщение */
struct my_data msg;
/* Структура данных пользователя?/
PhEvent_t *event;
/* Буфер событий */ ........
PhEventArm();
/* Установка proxy */
while( 1) { pid = Receive( 0, &msg, sizeof( msg));
/* Прием сообщений */
/* Запрос к Фотону на предмет принадлежности сообщения
и считывание события при положительном ответе */
switch( PhEventRead( pid, event, EVENT_SIZE)) {
case Ph_EVENT_MSG:
/* Обработка события */
PtEventHandler( event);
break;
case 0:
/* Сообщение не от Фотона */
...........
/* Код пользователя */
break;
case -1:
/* Ошибка запроса */
perror( "PhEventRead failed");
break;
}
}
}

[ Наверх ]

Разработка программ

Наверное, не ошибусь если скажу, что эта глава вызовет наибольший интерес у программистов. Хотя, в среде Photon могут создавать программы, как те, кто поработал с X или MS Windows, так и люди впервые столкнувшиеся с графическим интерфейсом. Разработчики Фотона позаботились о простоте и мощности интерфейса программиста, снабдив его редактором, обеспечивающим визуальное программирование - Application Builder.

Программы Фотона могут использовать несколько уровней программного обеспечения, представленного библиотечными функциями. На нижнем уровне пользователю предоставляется работать с графическими примитивами типа "линия", "текст" и им подобными. На верхнем уровне программирования пользователю доступны готовые элементы интерфейса, называемые виджеты (widgets). (Специалистов, не знакомых с X Window System, слово "виджет", возможно, введет в состояние задумчивости. Говоря коротко - это элемент интерфейса. Другие определения можно найти в [1] или [2]). Виджеты представляют собой объекты, о которых Фотон знает как управлять их поведением на экране. Преимущества такого подхода очевидны: программист не должен обладать информацией о деталях реализации того или иного объекта, ему нужно знать только функции, организующие интерфейс c этим виджетом, такие как, создание, уничтожение и управление ресурсами. Наряду с геометрическими ресурсами, такими как цвет, размер, положение в пространстве событий и т.п., каждый виджет поддерживает ресурс, представляющий собой список функций, определяемых программистом (callbacks) и выполняемых после получения какого-либо события. Например, в список ресурсов объекта "кнопка" можно внести функцию открытия нового окна и изменения вида кнопки после ее нажатия.

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

Простейший пример управления ресурсами виджетов на примере знаменитого "Hello World" приведен на листинге 1.

Теперь, реализуем ту же самую программу не прибегая к программированию в привычном смысле этого слова, а используя возможности Application Builder (рис. 5). Выигрывая в простоте и наглядности при разработке программы, мы немного теряем в наглядности полученного текста (листинг 2). Это не удивительно: если пользователь решил ограничиться визуальным программированием, скорее всего, он не станет вдаваться в детали достижения цели, а после окончания разработки просто нажмет кнопку "Run Application".

Нажмите на картинку


Рис. 5

[ Наверх ]

Несколько практических аспектов

Компактность

Самими разработчиками, Photon рекламируется как графическая оболочка для "embedded systems" [5,6,7]. Скорее всего, само понятие "встроенные системы" требует некоторой конкретизации: "что это за системы и куда они встроены" ? В лаконичной и красивой фразе "embedded systems" речь идет о любой реализации компьютера, отличной от той, которую вы видите на своем столе. Под эту классификацию попадают, в основном, компьютеры с ограниченными ресурсами памяти, как дисковой, так и оперативной.

Очевидно, что установка 16-32М ОЗУ на промышленный контроллер только для возможности визуализации процесса в X Window System, было бы непозволительной роскошью. Но на добавление 1-2М ради возможности получить удобный графический интерфейс, вероятнее всего, согласятся многие.

Так, например, необходимый для работы пользовательской программы набор, включающий ядро Фотона, графический драйвер и администратор окон, в сумме, занимают не более 360К ОЗУ.

Масштабируемость

Модульная архитектура Фотона позволяет настраивать систему по вашему требованию, добавляя или убирая определенный сервис. Например, когда вы не особенно ограничены в аппаратных ресурсах, т.е. работаете на компьютере, примерно, с 4-8М ОЗУ, вы легко можете себе позволить использовать менеджер рабочего стола (Photon Desktop Manager) либо свои сервисные утилиты. Так, одну и ту же программу, разработанную для мощной аппаратной платформы можно использовать в среде с ограниченными ресурсами без изменения кода, отказавшись от тех или иных возможностей.

Быстродействие

В подтверждение того что, что Photon, действительно, может снизить стоимость вашего проекта, фирма QSSL приложила максимум усилий для увеличения производительности графической среды. Действительно, Фотон достигает скорости воспроизведения графических объектов на экране, сравнимой с быстродействием графического драйвера. Таким образом, вы можете на системе с 386 процессором и простой VGA картой работать в оконной среде примерно с таким же уровнем комфорта как на 486DX2 в среде MS Windows.

Взаимодействие с другими графическими средами

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

[ Наверх ]

Литература:

  1. Valerie Quercia and Tim O'Reilly. X Window System User's Guide. Volume Three, 1993.
  2. Photon microGUI, Programer's Guide, // QNX Software Systems Ltd., 1995.
  3. Макарьев К., Кондратюк А. Знакомство с WATCOM C для QNX // Монитор. 1994. Вып. 5. С. 58-66.
  4. Dan Hildebrand. Building GUI Applications for QNX // QNXnews. 1993. Vol. 7. N. 4. pp. 30-31.
  5. Dan Hildebrand. Project Photon - Embedded Windowing for QNX // QNXnews. 1993. Vol. 7. N. 4. pp. 17-22.
  6. Rob Oakley. QNX Microkernel Technology: A Scalable Approach to Realtime Distributed and Embedded Systems // QNX Software Systems Ltd. brochure. 1994.
  7. It's Small, It's Scalable, and It Connects Seamlessly to Desktop GUIs - It's the Photon microGUI! // QNXnews. 1995. Vol. 9. N. 2. pp. 7-10.
  8. QNX System Architecture, // QNX Software Systems Ltd., 1995.

Листинг 1.
#include /* заголовочный файл описания типов виджетов */
#include main( int argc, char *argv[]) { PtWidget_t *window;
/* виджет главного окна */
PhArea_t area; /* размер и позиция виджета */
PtArg_t args[3]; /* массив для описания ресурсов */
area.pos.x = 20; /* координаты левого верхнего угла окна */

area.pos.y = 20; area.size.w = 200; /* размер окна */
area.size.h = 100; /* установить размер и позицию окна */
PtSetArg( &args[0], Pt_ARG_AREA, &area, 0);
/* установить заголовок окна */
PtSetArg( &args[1], Pt_ARG_WINDOW_TITLE, "My program", 0);
/* зарегистрировать задачу у ядра Фотона и создать виджет */
/* главного окна с параметрами, описанными выше */
window = PtAppInit( NULL, &argc, argv, 2, args);
area.pos.x = 20; /* координаты левого верхнего угла метки */

area.pos.y = 25; /* относительно координат окна */
area.size.w = 145; /* размер метки */
area.size.h = 35; /* установить размер и позицию метки */
PtSetArg( &args[0], Pt_ARG_AREA, &area, 0);
/* установить текст метки */
PtSetArg( &args[1], Pt_ARG_TEXT_STRING, "Hello World", 0);
/* установить фонт для текста метки */
PtSetArg( &args[2], Pt_ARG_TEXT_FONT, "helv24bi", 0);
/* создать виджет метки с параметрами, описанными выше, как */
/* потомок главного окна */
PtCreateWidget( PtLabel, window, 3, args); /* отобразить главный виджет со всеми потомками */
PtRealizeWidget( window ); /* обрабатывать получаемые события */
PtMainLoop(); }

Листинг 2
/* Standard headers */
#include
#include
#include
#include
/* Toolkit headers */
#include
#include
#include
/* Local headers */
#include "abimport.h"
#include "proto.h"
#include "abwidgets.h"
#include "ablinks.h"
#include "abevents.h"
#include "abvars.h"
/* AppBuilder globals */
char ab_exe_path[PATH_MAX];void main( int argc, char *argv[] )
{ /* AppBuilder Initialization */ ApInitialize( argc, argv );
/* Setup class table used by this application */ ApClassInit( );
/* Display main window */ ApLinkWindow( NULL, &appl_links[0], NULL );
/* Loop until user quits application */
PtMainLoop( ); }
void ApClassInit( ) { ApAddClass( "PtWindow", &PtWindow );
ApAddClass( "PtLabel", &PtLabel ); }

Ющенко С.В.
'Современные Технологии Автоматизации' 1/96

Рассказать друзьям:

Rambler's Top100           Рейтинг@Mail.ru