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