Библиотека LinCRT


 
Андрей Боровский
borovsky@pochtamt.ru
Введение
Зачем нужна LinCRT?
Лицензионное соглашение

Работа с LinCRT
Инициализация и завершение работы библиотеки
Окна
Ввод-вывод
Взаимодействие с мышью
Перерисовка экрана
Временный выход в оболочку
Совместимость с ncurses и CRT
 

Введение

Библиотека LinCRT (CRT для Linux) реализует дополнительные возможности при выводе данных на экран текстового терминала (вывод в цвете, произвольное позиционирование курсора, взаимодействие с мышью и т. п.). Библиотека сделана максимально совместимой с библиотекой CRT для Turbo Pascal.Эта библиотека написана на основе нескольких подпрограмм, которые я написал для использования в своих проектах. Выпуская первую версию, я хотел бы знать, насколько эта библиотека полезна для других программистов. Если у вас возникнут замечания или предложения - пишите мне.

Зачем нужна LinCRT?

В Linux существует специальная библиотека для форматированного вывода на экран терминала, которая называется ncurses. LinCRT основана на ncurses (она использует написанный мной модуль NCurses, в котором объявляются функции библиотеки ncurses) и ее возможности несколько ограничены по сравнению с ncurses. Тем не менее, я считаю, что такая библиотека будет весьма полезна. Во-первых, значительная совместимость с CRT позволит программистам, которые (как и я) когда-то работали на Turbo Pascal с CRT, быстрее освоить программирование терминала под Linux. Во-вторых, LinCRT позволяет использовать родные для Паскаля процедуры Write, WriteLn и ReadLn, что, по-моему, гораздо удобнее, чем использование функций waddstr и wgetstr из ncurses. В-третьих, на основе этой библиотеки можно разработать аналогичный модуль для Windows и обеспечить таким образом кросс-платформенную переносимость. 

Лицензионное соглашение

Библиотека LinCRT (c) 2002 Андрей Боровский. Все права защищены.

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

ВЫ ИСПОЛЬЗУЕТЕ ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ НА СВОЙ СТРАХ И РИСК. АВТОР ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ НЕ НЕСЕТ ОТВЕТСТВЕННОСТЬ ЗА ПОТЕРЮ ДАННЫХ, ПОВРЕЖДЕНИЯ ОБОРУДОВАНИЯ, ПОТЕРИ ПРИБЫЛИ ИЛИ ЛЮБЫЕ ДРУГИЕ ВИДЫ ПОТЕРЬ, ПРЯМЫХ ИЛИ КОСВЕННЫХ, СВЯЗАННЫХ С ИСПОЛЬЗОВАНИЕМ (ПРАВИЛЬНЫМ ИЛИ НЕПРАВИЛЬНЫМ) ДАННОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ.

Работа с LinCRT.

Инициализация и завершение работы библиотеки

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

Окна

Важным понятием LinCRT является окно. Окно - это прямоугольная область экрана, в которую выводится информация. После инициализации LinCRT создается окно, размеры которого совпадают с размерами экрана терминала. При помощи функции Window можно открыть окна любых размеров, занимающие произвольное положение на экране.

Ввод-вывод.

LinCRT позволяет выполнять операции ввода-вывода при помощи стандартных процедур ReadLn, Write, WriteLn. Использование процедуры Read может привести к ошибкам. Вывод отдельных символов осуществляется процедурами PutChar и PutCharXY. Особенность этих процедур заключается в том, что они не меняют текущее положение курсора. Для ввода отдельных символов служат функции ReadKey и GetKey. Эти функции не отображают вводимые символы на экране. Функция ReadKey совместима с одноименной функцией из CRT. С не-текстовыми символами эта функция работает также, как и ее аналог из CRT. В режиме поддержки мыши (см. ниже) в ответ на нажатие кнопки мыши повторный вызов ReadKey возвращает значение 255. Функция GetKey является расширенным вариантом ReadKey. Эта функция возвращает значение типа Word. В случае нажатия текстовой клавиши GetKey возвращает код соответствующего символа. В случае нажатия не-текстовой клавиши функция возвращает одну из специальных псевдосимвольных констант, определенных в модуле LinCRT, и соответствующих аналогичным константам ncurses.

Функции ReadKey и GetKey являются блокирующими (т. е. приостанавливают выполнение программы до тех пор, пока не поступит ввод с клавиатуры). Для того, чтобы организовать неблокирующий ввод с помощью этих функций, следует воспользоваться функцией KeyPressed:

if KeyPressed then Key := ReadKey;

Примечание: Из-за ошибок в ncurses рекомендуется вызывать процедуру ReadLine в собственном, специально для нее открытом окне.

Взаимодействие с мышью

При выполнении консольной программы в окне терминала X-Windows система позволяет приложению обрабатывать сообщения мыши. Для того, чтобы включить поддержку мыши в LinCRT-приложении, необходимо обратиться к процедуре InitMouse. В режиме поддержки мыши в ответ на нажатие кнопок мыши функция GetKey будет возвращать специальные псевдосимвольные коды. Определить положение мыши в момент последнего нажатия кнопки можно при помощи функции WhereMouseXY.

Отключить поддержку мыши в приложении можно при помощи процедуры KillMouse.

Примечание: В режиме поддержки мыши функция KeyPressed возвращает значение True, если была нажата кнопка мыши.

Перерисовка экрана

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

В LinCRT определена переменная OnTermResize типа TOnTermResize. Определение этого типа выглядит следующим образом:

TOnTermResizeProc = procedure(DoingInput : Boolean);

Определите процедуру перерисовки экрана в соответствии с этим заголовком и назначьте ее переменной OnTermResize. Эта процедура будет вызываться всякий раз при изменении размеров экрана. Параметр DoingInput принимает значение True, если изменение размеров экрана произошло во время вызова процедуры ReadLn. Вы можете изменить положение курсора и ввод ReadLn продолжится с новой позиции.

Учтите, что в момент перерисовки экрана открытое ранее окно будет закрыто (если только это не окно StdScr), и вам придется открыть его заново. Текущие значения числастрок и столбцов экрана хранятся в переменных ScrLines и ScrCols соответственно. При передаче управления вашей процедуре в эти переменные будут записаны новые значения.

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

BreakOnResize := True;
...
ReadLn(SomeValue);
if Broken then ... //размеры экрана изменились 
else ... // пользователь нажал [Enter]. 

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

Временный выход в оболочку

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

Примечание: После возврата из оболочки следует перерисовать экран LinCRT.

Совместимость с ncurses и CRT

LinCRT допускает непосредственные вызовы функций ncurses (например, при помощи модуля NCurses). Так как многим функциям ncurses, работающим с окнами, требуется идентификатор окна, над которым следует выполнить операцию, модуль LinCRT экспортирует две переменные типа PWINDOW: StdScr и CurWnd. Переменная StdScr соответствует окну экрана, созданному при вызове initscr(), а переменная CurWnd – текущему окну (в данной версии LinCRT ввод/вывод может выполняться только в одном открытом в данный момент окне).

При совместной работе с LinCRT и ncurses необходимо учитывать следующее: отсчет координат курсора и окон в ncurses начинается с 0, тогда как в LinCRT (как и в CRT) отсчет координат начинается с единицы. Функции ввода LinCRT функционируют корректно только в режиме keypad(True). Если вы изменили этот режим, не забудьте восстановить его перед обращением к функциям ввода LinCRT.

В LinCRT, как и в CRT, координаты курсора и окна  являются значениями типа Byte (а не Integer, как в ncurses). LinCRT использует те же константы для обозначения цветов, что и CRT, но численные значения констант не совпадают.

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

В ncurses цвета символов на экране определяются парами фон/текст. В LinCRT цвета фона и символов определяются также как и в CRT, т. е. по отдельности. Процедуры LinCRT преобразуют значения цветов в пары ncurses. LinCRT использует для обозначения цветов те же константы, что и CRT, но численные значения констант не совпадают.

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

Имя

Примечание

Процедуры и функции

AssignCrt

Используйте InitLinCRT

Delay

Используйте __sleep

HighVideo

 

LowVidio

 

NormVidio

 

NoSound

 

Sound

 

TextMode

 

Переменные

CheckBreak

 

CheckEOF

 

CheckSnow

 

DirectVideo

 

LastMode