3.3. Дополнительные возможности Xt.

3.3.1. Ввод данных из файла или из внешнего устройства.

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

XtInputId XtAppAddInput (XtAppContext prAppContext, int nSource, XtPointer pCondition, XtInputCallbackProc pProcedure, XtPointer pUserData);

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

ЗначениеОписание
XtInputReadMaskфайл используется только для чтения данных
XtInputWriteMaskфайл используется для записи данных
XtInputExceptMaskпроцедура регистрируется для обработки ошибок
XtInputNoneMaskввода-вывода нет, регистрируемая функция не вызывается

Заметим, что указанные константы не объединяются с помощью оператора OR ( | ).

    Четвертый аргумент задает регистрируемую процедуру. Пятый аргумент используется для передачи данных в pProcedure при ее вызове.

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

    Процедура чтения/записи данных и обработки ошибок должна иметь следующий прототип:

void InputDataProc (XtPointer pData, int *nSource, XtInputId *nIdentificator);

    Здесь первый аргумент определяет данные, являющиеся последним параметром в вызове процедуры XtAppAddInput( ). Второй аргумент задает дескриптор файла (устройства), а третий аргумент есть идентификатор, возвращенный процедурой XtAppAddInput( ).

    Когда обмен данными закончен, зарегистрированную функцию надо удалить с помощью

XtRemoveInput (XtInputId nIdentificator).

    Процедура XtAppAddInput( ) полностью аналогична описанной выше процедуре XtAppAddInput( ) за исключением того, что в ней отсутствует аргумент, указывающий на контекст программы.

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

. . . . . . GetFileInputData(XtPointer pUserData, int *nSource, XtInputId *identifier) { char anBuffer [BUFSIZ]; int nCountBytes; char *p = (char*) pUserData; if ( (nCountBytes = read (*nSource, anBuffer, BUFSIZ) ) == -1) perror("GetFileInputData"); else printf("%s : %d bytes\n", p, nCountBytes); } main (int argc, char **argv) { XtAppContext prAppContext; Widget prTopLevelWidget; int nId; char *pS = "Read data from TESTFILE"; prTopLevelWidget = XtVaAppInitialize(&prAppContext, "XFileInput", NULL, 0, &argc, argv, NULL, NULL); if (nId = open("TESTFILE", O_RDONLY, S_IREAD) )<0 { fprintf(stderr, "xfileinput:I/O error\n"); exit (1); } XtAppAddInput(prAppContext, nId, XtInputReadMask, GetFileInputData, (XtPointer) pS); XtRealizeWidget(prTopLevelWidget); XtAppMainLoop(prAppContext); }

    Здесь программа открывает файл с именем "TESTFILE" и читает из него данные при помощи процедуры GetFileInputData( ). Мы использовали последний аргумент функции XtAppAddInput( ) для передачи строки, которая должна печататься, если чтение прошло успешно. Заметим, что, вообще говоря, функции read( ) и open( ) являются системно-зависимыми, поэтому, прежде чем использовать приведенный фрагмент кода, следует убедиться в том, что указанные процедуры будут работать корректно в операционной системе, установленной на компьютере.