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