XmContainer and XtAppAddTimeOut()

This forum is read only. No new submissions are accepted.

Questions about motif? Contact us

6 posts / 0 new
Last post
XmContainer and XtAppAddTimeOut()

Submitted by Anonymous on Mon, 09/30/2002 - 21:39. Developers
Hi,

I have a problem when I use XtAppAddTimeOut in a GUI that
contains the XmContainer widget. I schedule a timer when the
program starts and in the timer callback, I schedule the timer
again, i.e.

main() {
{
/* create tree here */

XtAppAddTimeOut(app_context, 2000,
(XtTimerCallbackProc)timer_callback, NULL);

XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}

static void timer_callback(XtPointer client_data, XtIntervalId *timer)
{
printf("tick
");

XtAppAddTimeOut(app_context, 2000,
(XtTimerCallbackProc)timer_callback, NULL);
}

The timer works OK until I use the GUI a lot (e.g. expand and
collapse tree nodes, and select tree nodes consecutively so many
times), then the timer never gets scheduled again. Some times it
works just fine!

Even when I disable drag and drop using the resource file
MyTreeProgram*dragInitiatorProtocolStyle XmDRAG_NONE
MyTreeProgram*dragReceiverProtocolStyle XmDRAG_NONE
at some point, after GUI use as explained above, the timer
callback is not called again.

Note that the above code works fine for other non-trivial
applications that contain other GUI elements except the
Container.

Any ideas??

Thanks

ICS_support

The Xt timer code is very solid. I`d suspect that there is something else in your application that is writing out of its bounds and happening to interfere with this operation of timers. Have you run the application using AcquaProva or Purify or another debugger which can check run-time boundaries?

Anonymous

Hi dbl,

Thanks for your prompt reply. Here is the complete source code

-----------------------------------------------------------
static Widget top_level;
static XtAppContext app_context;
static Widget tree;

int main(int argc, char **argv)
{
Widget main_window, main_form;

XtSetLanguageProc(NULL, NULL, NULL);

top_level = XtVaAppInitialize(&app_context, "MyTreeProgram",
NULL, 0, &argc, argv,
NULL, NULL);
main_window = XtVaCreateManagedWidget("main_window",
xmMainWindowWidgetClass, top_level,
NULL);
main_form = XtVaCreateManagedWidget("main_form",
xmFormWidgetClass, main_window,
NULL);
tree = XtVaCreateWidget("tree",
xmContainerWidgetClass, main_form,
XmNlayoutType, XmOUTLINE,
XmNautomaticSelection, XmAUTO_SELECT,
XmNentryViewType, XmSMALL_ICON,
NULL);

/* Create tree nodes */
populate_tree();

XtAppAddTimeOut(app_context, 2000,
(XtTimerCallbackProc)timer_cb, NULL);

XtManageChild(tree);
XtManageChild(main_form);

XtRealizeWidget(top_level);
XtAppMainLoop(app_context);
}

static void timer_cb(XtPointer client_data, XtIntervalId *timer)
{
time_t now = time(NULL);
char str[64];

cftime(str, "%T", &now);
printf("timer_cb %s
", str);
XtAppAddTimeOut(app_context, 2000,
(XtTimerCallbackProc)timer_cb, NULL);
}

static void populate_tree() {
int i, j, k;
char node_name[128];
Widget level1, level2, level3;

for(i=0; i<2; i++) {
sprintf(node_name, "Node_%d", i+1);
level1 = XtVaCreateManagedWidget(node_name,
xmIconGadgetClass, tree,
XmNoutlineState, XmEXPANDED,
XmNshadowThickness, 0,
NULL);

for(j=0; j<2; j++) {
sprintf(node_name, "Node_%d_%d", j+1, i+1);
level2 = XtVaCreateManagedWidget(node_name,
xmIconGadgetClass, tree,
XmNentryParent, level1,
XmNoutlineState, XmEXPANDED,
XmNshadowThickness, 0,
NULL);

for(k=0; k<3; k++) {
sprintf(node_name, "Node_%d_%d_%d",
k+1, j+1, i+1);
level3 = XtVaCreateManagedWidget(node_name,
xmIconGadgetClass, tree,
XmNentryParent, level2,
XmNshadowThickness, 0,
NULL);
}
}
}
}
-----------------------------------------------------------

As you can see, I`m not doing any thing special there.
I haven`t used any debugger.
I looked at the XmContainer.c in openmotif 2.1.30, and I found that a timer is used to detect double clicks and things like that. Could this be interfering with my timer??
Also, what happens when a timer expires while the application is busy processing events, e.g. timer expires at t=1 sec. and
application is busy between t=0 and 2 sec.? Does it just ignore the timer event or delay its processing until it`s free? I assume it delays the processing, but it appears to me that this is not what is happening here.

I appreciate your feedback and thanks for your time.

inas

ICS_support

Timers should be handled after Xt returns to the event loop. Only if XmContainer is *processing* events -- and discarding timers -- should the timers fail to fire. Xt calculates the timer information in its event loop; the timers are not expiring in the background and do not interrupt the application.

Anonymous

Hi dbl,

I assume

> Only if XmContainer is *processing* events -- and discarding
> timers -- should the timers fail to fire.

means that it is possible that my timer fails to fire, and thus I can`t count on it to always be there (since it reschedules itself in the timer callback).

I tried to use setitimer() to produce SIGALRM periodically and install a signal handler for it, i.e.

-------------------------------------------------------
main()
{
struct itimerval itimer_val;

setitimer(ITIMER_REAL, &itimer_val, NULL);
sigset(SIGALRM, sig_handler);
sig_id = XtAppAddSignal(app_context, safe_signal_handler, NULL);
}

void sig_handler(int unused)
{
XtNoticeSignal(sig_id);
}

void safe_signal_handler(XtPointer client_data, XtSignalId *Id)
{
timer_id = XtAppAddTimeOut(app_context, 0,
(XtTimerCallbackProc)timer_cb, NULL);
}
-------------------------------------------------------

I modified one of the examples in Motif Programming Manual Vol. 6A by A. Fountain, to come up with the above code.
It seems to work fine. I was wondering if you know of any potential problems with handling UNIX signals in the above manner.

Thanks again for your help.

ICS_support

I`d just try to figure out why the timers aren`t working for you, rather than go this route -- in which you are still depending on Xt to notice that a signal has been set and to dispatch it to your application.

The Xt code really just does linked-list manipulation, so it`s pretty easy to trace through a debugged version of Timer.c. You`ll see the requests come in and be handled.