В 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( ) являются системно-зависимыми, поэтому, прежде чем использовать приведенный фрагмент кода, следует убедиться в том, что указанные процедуры будут работать корректно в операционной системе, установленной на компьютере.