|
8. Экранные библиотеки и работа с видеопамятью. Терминал в UNIX с точки зрения программ - это файл. Он представляет собой два устройства: при записи write() в этот файл осуществляется вывод на экран; при чтении read()-ом из этого файла - читается информация с клавиатуры. Современные терминалы в определенном смысле являются устройствами прямого доступа:
Традиционные терминалы являются самостоятельными устройствами, общающимися с компьютером через линию связи. Протокол* - общения образует систему команд терминала и может быть различен для терминалов разных моделей. Поэтому библиотека работы с традиционным терминалом должна решать следующие проблемы:
В UNIX эти задачи решает стандартная библиотека curses (а только первую задачу более простая библиотека termcap). Для настройки на систему команд конкретного дисплея эти библиотеки считывают описание системы команд, хранящееся в файле /etc/termcap. Кроме них бывают и другие экранные библиотеки, а также существуют иные способы работы с экраном (через видеопамять, см. ниже). В задачах данного раздела вам придется пользоваться библиотекой curses. При компиляции программ эта библиотека подключается при помощи указания ключа -lcurses, как в следующем примере:
cc progr.c -Ox -o progr -lcurses -lm
Здесь подключаются две библиотеки:
В начале своей программы вы должны написать директиву
#include <curses.h>
подключающую файл /usr/include/curses.h, в котором описаны форматы данных, используемых библиотекой curses, некоторые предопределенные константы и.т.п. (это надо, чтобы
ваша программа пользовалась именно этими стандартными соглашениями). Посмотрите в этот файл!
Когда вы пользуетесь curses-ом, вы НЕ должны пользоваться функциями стандартной библиотеки stdio для непосредственного вывода на экран; так вы не должны пользоваться функциями printf, putchar. Это происходит потому, что curses хранит в памяти процесса копию содержимого экрана, и если вы выводите что-либо на экран терминала обходя функции библиотеки curses, то реальное содержимое экрана и позиция курсора на нем перестают соответствовать хранимым в памяти, и библиотека curses начнет выводить неправильное изображение.
ПРОГРАММА
| |
| CURSES---копия экрана
| printw,addch,move
| |
V V
библиотека STDIO --printf,putchar----> экран
Таким образом, curses является дополнительным "слоем" между вашей программой и стандартным выводом и игнорировать этот слой не следует.
Напомним, что изображение, создаваемое при помощи библиотеки curses, сначала формируется в памяти программы без выполнения каких-либо операций с экраном дисплея (т.е. все функции wmove, waddch, waddstr, wprintw изменяют только ОБРАЗЫ окон в памяти, а на экране ничего не происходит!). И лишь только ПОСЛЕ того, как вы вызовете функцию refresh() ("обновить"), все изменения происшедшие в окнах будут отображены на экране дисплея (такое одновременное обновление всех изменившихся частей экрана позволяет провести ряд оптимизаций). Если вы забудете сделать refresh - экран останется неизменным. Обычно эту функцию вызывают перед тем, как запросить у пользователя какой-либо ввод с клавиатуры, чтобы пользователь увидел текущую "свежую" картинку. Хранение содержимого окон в памяти программы позволяет ей считывать содержимое окон, тогда как большинство обычных терминалов не способны выдать в компьютер содержимое какой-либо области экрана. Общение с терминалом через линию связи (или вообще через последовательный протокол) является довольно медленным. На персональных компьютерах существует другой способ работы с экраном: через прямой доступ в так называемую "видеопамять" - специальную область памяти компьютера, содержимое которой аппаратно отображается на экране консоли. Работа с экраном превращается для программиста в работу с этим массивом байт (запись/чтение). Программы, пользующиеся этим способом, просты и работают очень быстро (ибо доступ к памяти черезвычайно быстр, и сделанные в ней изменения "проявляются" на экране почти мгновенно). Недостаток таких программ - привязанность к конкретному типу машины. Эти программы немобильны и не могут работать ни на обычных терминалах (подключаемых к линии связи), ни на машинах с другой структурой видеопамяти. Выбор между "традиционной" работой с экраном и прямым доступом (фактически - между мобильностью и скоростью) - вопрос принципиальный, тем не менее принятие решения зависит только от вас. Видеопамять IBM PC в текстовом режиме 80x25 16 цветов имеет следующую структуру:
struct symbol{ /* IBM PC family */
char chr; /* код символа */
char attr; /* атрибуты символа (цвет) */
} mem[ 25 ] [ 80 ]; /* 25 строк по 80 символов */
Структура байта атрибутов:
------------------------------------------
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | # бита
------------------|-----------------------
|blink| R | G | B | intensity | r | g | b | цвет
------------------|-----------------------
background (фон) | foreground (цвет букв)
R - red (красный) G - green (зеленый) B - blue (синий)
blink - мерцание букв (не фона!) intensity - повышенная яркость Координатная система на экране: верхний левый угол экрана имеет координаты (0,0), ось X горизонтальна, ось Y вертикальна и направлена сверху вниз. Цвет символа получается смешиванием 3х цветов: красного, зеленого и синего (электронно-лучевая трубка дисплея имеет 3 электронные пушки, отвечающие этим цветам). Кроме того, допустимы более яркие цвета. 4 бита задают комбинацию 3х основных цветов и повышенной яркости. Образуется 2**4=16 цветов:
I R G B номер цвета
BLACK 0 0 0 0 0 черный
BLUE 0 0 0 1 1 синий
GREEN 0 0 1 0 2 зеленый
CYAN 0 0 1 1 3 циановый (серо-голубой)
RED 0 1 0 0 4 красный
MAGENTA 0 1 0 1 5 малиновый
BROWN 0 1 1 0 6 коричневый
LIGHTGRAY 0 1 1 1 7 светло-серый (темно-белый)
DARKGRAY 1 0 0 0 8 темно-серый
LIGHTBLUE 1 0 0 1 9 светло-синий
LIGHTGREEN 1 0 1 0 10 светло-зеленый
LIGHTCYAN 1 0 1 1 11 светло-циановый
LIGHTRED 1 1 0 0 12 ярко-красный
LIGHTMAGENTA 1 1 0 1 13 ярко-малиновый
YELLOW 1 1 1 0 14 желтый
WHITE 1 1 1 1 15 (ярко)-белый
Физический адрес видеопамяти IBM PC в цветном алфавитно-цифровом режиме (80x25,
16 цветов) равен 0xB800:0x0000. В MS DOS указатель на эту память можно получить при
помощи макроса make far pointer: MK_FP (это должен быть far или huge указатель!). В
XENIX** - указатель получается при помощи системного вызова ioctl, причем система предоставит вам виртуальный адрес, ибо привелегия работы с физическими адресами в UNIX
принадлежит только системе. Работу с экраном в XENIX вы можете увидеть в примере
"осыпающиеся буквы".
* - Под протоколом в программировании подразумевают ряд соглашений двух сторон (сервера и клиентов; двух машин в сети (кстати, термин для обозначения машины в сети "host" или "site")) о формате (правилах оформления) и смысле данных в передаваемых
друг другу сообщениях. Аналогия из жизни - человеческие речь и язык. Речь всех людей состоит из одних и тех же звуков и может быть записана одними и теми же буквами
(а данные - байтами). Но если два человека говорят на разных языках - т.е. поразному конструируют фразы и интерпретируют звуки - они не поймут друг друга!
** - XENIX - (произносится "зиникс") версия UNIX для IBM PC, первоначально разработанная фирмой Microsoft и поставляемая фирмой Santa Cruz Operation (SCO).
[Назад][Содержание][Вперед] |