3.3.2. Таймер.

    Xt предоставляет приложению возможность выполнять определенные действия через заданные промежутки времени. Например, периодически отображать на экране текущее время в заданном окне и т.д. Для указанных целей используется специальный механизм Xt - таймер. Он обеспечивает вызов через заданный интервал времени специальной функции, заданной программой. Таймер создается, например процедурой

XtIntervalId XtAppAddTimeOut (XtAppContext prAppContext,
     unsigned long nInterval, XtTimerCallbackProc pProcedure,
     XtPointer pUserData);

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

    Процедура возвращает значение типа XtIntervalId, которое однозначно идентифицирует зарегистрированный таймер и которое затем может быть использовано в качестве аргумента в процедуре XtRemoveTimeOut (XtIntervalId), предназначенной для уничтожения таймера.

    Регистрируемая функция, должна иметь следующий прототип:

void TimerProc (XtPointer pUserData, XtIntervalId *Id);

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

    Отметим, что таймер автоматически уничтожается при вызове соответствующей процедуры. Поэтому, если необходимо, чтобы таймер функционировал н периодически проявлял себя каждые nInterval миллисекунд, в вызываемой функции он должен пересоздаваться с помощью XtAppAddTimeOut( ).

    Таймер может быть создан и зарегистрирован с помощью процедуры XtAddTimeOut( ), которая отличается от описанной выше функции XtAppAddTimeOut( ) только отсутствием аргумента prAppContext.

    Ниже приведен фрагмент кода, содержащий пример использования таймера.

void Count (Widget prWidget, XtIntervalId  *Id)
{
     static int n = 0;

     if (n<10)  {
        XtAppAddTimeOut(XtWidgetToApplicationContext (prWidget),
			1000, Count, prWidget);

        n++;
        printf ("%d seconds.\n", n);
  }
  else
    exit(0);
}

void main (int argc, char  **argv)
{
    XtAppContext  prAppContext;
    Widget	  prTopLevelWidget;
    int		  nId;

    prTopLevelWidget = XtVaAppInitialize (&prAppContext,
			"Timer", NULL, 0,
		          &argc, argv, NULL, NULL);
    XtAppAddTimeOut(prAppContext, 1000, Count,
		          prTopLevelWidget);
    XtRealizeWidget(prTopLevelWidget);
    XtAppMainLoop(prAppContext);
}

    В данном случае таймер работает, как секундомер, отсчитывая десять секунд, после чего программа завершается.

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