Работа с окнами

Возможности создания окон, групп и организация их в иерархию

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

Следует создавать группы окон, чтобы организовывать, отображать и управлять окнами в приложении. Группа окон состоит из родительского окна и хотя бы одного дочернего. Чтобы создать группу, окно должно вызвать функцию screen_create_window_group() и указать ее имя. Имя группы окон может передаваться другим функциям, потокам или процессам, которые отвечают за создание дочерних окон. Любое дочернее окно может присоединиться к этой группе, если оно имеет ассоциированное имя группы. Родительское окно уведомляется каждый раз, когда дочернее окно присоединяется к группе. В уведомление включается дескриптор окна, позволяющий родительскому окну контролировать некоторые свойства дочернего, например, видимость, положение, размер и z-индекс. Родительское окно не может получить доступ к оконным буферам дочерних. Дочернее окно остается невидимым до тех пор, пока оно не будет добавлено в группу окон и станет видимым владельцем группы.

Следующие разделы справки демонстрируют общие практики выполнения типичных операций с окнами:

Виды окон
Параметры окон
Пиксельные форматы
Родительские отношения и позиционирование
Создание окон
Создание дочерних окон

Виды окон

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

Тип окна определяется на этапе создания. Существуют следующие типы окон.

SCREEN_APPLICATION_WINDOW
Этот тип окна используется для отображения основного окна приложения. Координаты окна в этом случае определяются относительно разрешения экрана. Окно этого типа может использоваться для отображения приложения в полноэкранном режиме:

app_window-1.png
Рисунок 1. Полноэкранное приложение

Параметры окон

Параметры окон в Screen API

Screen различает свойства, доступные родителю и владельцу.

Параметры окна, доступные родителю

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

Параметры окна, доступные владельцу

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

Пиксельные форматы

Форматы пикселей окна определяют способ хранения информации в памяти GPU

Модель RGBA использует цветовое кодирование Red Green Blue (RGB) с дополнительной информацией об альфа канале (уровень прозрачности). Приложения, которым не требуется альфа-смешивание, могут использовать форматы, имеющие в качестве альфа-компонента отметку X.

Screen API поддерживает следующие форматы пикселей окон (описание этих форматов доступно на сайте www.fourcc.org):

Формат Описание
SCREEN_FORMAT_BYTE1
SCREEN_FORMAT_RGBA4444 16 бит-на-пиксель; (4 бит на канал) RGB с альфа каналом.
SCREEN_FORMAT_RGBX4444 16 бит-на-пиксель; (4 бит на канал) RGB с альфа каналом (альфа канал игнорируется).
SCREEN_FORMAT_RGBA5551 16 бит-на-пиксель; 2 байта содержат R, G, и B компоненты (5 бит на канал и 1 бит на альфа компонент).
SCREEN_FORMAT_RGBX5551 16 бит-на-пиксель; 2 байта содержат R, G, и B компоненты (5 бит на канал и 1 бит на альфа компонент, который игнорируется).
SCREEN_FORMAT_RGB565 16 бит-на-пиксель; 5 бит на R и B компоненты и 6 бит для G. Формат представляет следующий порядок бит (от старшего байта к младшему): RRRRRGGG GGGBBBBB.
SCREEN_FORMAT_RGB888 24 бит-на-пиксель; (8 бит на канал) RGB.
SCREEN_FORMAT_RGBA8888 32 бит-на-пиксель; (8 бит на канал) RGB с альфа каналом.
SCREEN_FORMAT_RGBX8888 32 бит-на-пиксель; (8 бит на канал) RGB с альфа каналом (альфа канал игнорируется).
SCREEN_FORMAT_YVU9 9 бит-на-пиксель; YUV формат. 8-bit Y поверхность и 8-bit 4x4 субсэмплированные V и U поверхности. Зарегистрирован Intel.
SCREEN_FORMAT_YUV420 Стандартный формат передачи NTSC TV.
SCREEN_FORMAT_NV12 12 бит-на-пиксель; YUV формат. 8-bit Y поверхность и 2x2 субсэмплированные, чередующиеся U и V поверхности.
SCREEN_FORMAT_YV12 12 бит-на-пиксель; YUV формат. 8-bit Y поверхность и 8-bit 2x2 субсэмплированные U и V поверхности.
SCREEN_FORMAT_UYVY 16 бит-на-пиксель; упакованный YUV формат. YUV 4:2:2 — Y сэмпл в каждом пикселе, U и V сэмплы в каждом втором пикселе горизонтально на каждой линии. Макропиксель содержит 2 пикселя в 1 типе u_int32.
SCREEN_FORMAT_YUY2 16 бит-на-пиксель; упакованный YUV формат. YUV 4:2:2 как в UYVY, но с отличным порядком компонентов в u_int32 макропикселе.
SCREEN_FORMAT_YVYU 16 бит-на-пиксель; упакованный YUV формат. YUV 4:2:2 как в UYVY, но с отличным порядком компонентов в u_int32 макропикселе.
SCREEN_FORMAT_V422 Упакованный YUV формат. Инвертированная версия UYVY.
SCREEN_FORMAT_AYUV Упакованный YUV формат. Комбинируется YUV и альфа канал.

Также в Screen API поддерживаются следующие дополнительные форматы:

Формат Описание
SCREEN_FORMAT_BGRA8888 32 бит-на-пиксель; (8 бит на канал) RGB с альфа каналом. Формат представляет следующий порядок бит (от старшего байта к младшему): BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA.
SCREEN_FORMAT_BGR565 16 бит-на-пиксель; 5 бит на R и B компоненты и 6 бит для G. Формат представляет следующий порядок бит (от старшего байта к младшему): BBBBBGGG GGGRRRRR
SCREEN_FORMAT_BGRA5551 16 бит-на-пиксель; 2 байта содержат R, G, и B компоненты (5 бит на канал и 1 бит на альфа компонент). Формат представляет следующий порядок бит (от старшего байта к младшему): BBBBBGGG GGRRRRRA.

Родительские отношения и позиционирование

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

Следующие параметры окон определяются относительно родительского окна:

visibility
Дочернее окно может быть видимо только в том случае, когда видимо родительское.
z-order
Z-индекс дочернего окна вычисляется относительно z-индекса родительского. Если z-индекс дочернего окна положительный, тогда оно будет располагаться выше родительского окна. В противном случае родительское окно будет перекрывать дочернее.
position
Координаты дочернего окна определяются относительно левого-верхнего угла родительского окна. Произвольные перемещения родительского окна также учитываются.
size
Размер окна определяется относительно родительского. Любое масштабирование родительского окна также применяется и к дочерним.
transparency
Глобальное значение альфа-канала дочернего окна комбинируется с родительским.

Окно приложения

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

Создание окон

Перед отображением контента необходимо создание окна приложения. Представленная процедура описывает общие способы создания окон. Для создания окна:

  1. Создаются переменные для хранения контекста, окна и имени группы.

    screen_context_t screen_context = 0;
    screen_window_t screen_window = 0;
    static const char *window_group_name = "mainwindowgroup";

  2. Далее создается контекст. Контекст определяет взаимоотношения между приложением и оконной подсистемой.

    screen_create_context( &screen_context, SCREEN_APPLICATION_CONTEXT );

  3. Создается окно. Функция screen_create_window() принимает на вход указатель на переменную для хранения дескриптора окна и созданный дескриптор контекста.

    screen_create_window( &screen_window, screen_context );

  4. Следующим шагом создается группа окон. Переменная window_group_name задает имя группы окон. Имя группы окон должно быть уникальным. Для того чтобы сделать окно приложения видимым, следует добавить его в группу окон.

    screen_create_window_group( screen_window, window_group_name );

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

    int format = SCREEN_FORMAT_RGBA8888;
    screen_set_window_property_iv( screen_window, SCREEN_PROPERTY_FORMAT, &format );
    int usage = SCREEN_USAGE_NATIVE;
    screen_set_window_property_iv( screen_window, SCREEN_PROPERTY_USAGE, &usage );

  6. Создайте видео-буфера для окна. В примере буфер используется для хранения видеоданных окна. Функция screen_create_window_buffers() принимает дескриптор окна и число, определяющее количество буферов, создаваемых для этого окна.

    screen_create_window_buffers( screen_window, 1 );

Хотя все задействованные ресурсы уничтожаются при терминировании приложения, лучше всего уничтожить вручную все созданные окна, pixmap-ы и контексты.

Следующий код освобождает задействованные в примере ресурсы.

screen_destroy_window( screen_window );
screen_destroy_context( screen_context );

Создание дочерних окон

Для создания дочерних окон может использоваться функция screen_create_window_type().

Для создания дочернего окна:

  1. Создаются переменные для хранения контекста и окна.

    screen_context_t screen_context = 0;
    screen_window_t screen_child_window = 0;

  2. Создание контекста. Контекст определяет взаимоотношения между приложением и оконной подсистемой.

    screen_create_context( &screen_context, SCREEN_APPLICATION_CONTEXT );

  3. Создание дочернего окна. Функция screen_create_window_type() позволяет создать в рамках контекста окно. В данном случае тип окна должен быть установлен в SCREEN_CHILD_WINDOW.

    int wintype = SCREEN_CHILD_WINDOW;
    screen_create_window_type( &screen_child_window, screen_context, wintype );

  4. Присоединение окна к группе. Функция screen_join_window_group() должна принимать на вход имя группы, созданной родительским (или системным) окном.

    screen_join_window_group( screen_child_window, window_group_name );




Предыдущий раздел: Оконная подсистема Screen