Re: XForms: Xwindows with xforms

Stephen Huyssoon (huyssoons@advancia.com)
Fri, 23 Apr 1999 13:19:01 -0500

# To subscribers of the xforms list from Stephen Huyssoon <huyssoons@advancia.com> :

Liana Lorigo wrote:

> # To subscribers of the xforms list from Liana Lorigo <liana@ai.mit.edu> :
>
> Hello,
>
> I am having difficulty using xforms with Xwindows events:
>
> I would like to render to a window that can run an
> "XtAppMainLoop(app)" call, but so that this call is interrupted (and
> control returns to my xforms gui) when xforms buttons are pressed.
>
> Does anyone know how to implement this switch of control flow?
>
> Perhaps I could include the source of the XtAppMainLoop routine in an
> idle_callback?
>
> Does anyone have experience with this or ideas about it?
>
> Thanks,
> Liana Lorigo
> MIT AI Lab

Try this on for size.
I *always* handle my events this way. I never give control
to any library. It keeps me happy.

Serge B Bromow wrote:
>
> Hello Stephen
>
> I am a new comer to Xforms and have been delighted
> with it's simplicity and elegance. I have translated
> a number of legacy programs to the Xforms look and
> feel with little or no problems.
>
> However there are a number of applications that use
> touch screen interfaces and I was concerned that
> I may not be able to use the forms library since I do
> not have direct or advanced access to the event handler.
>
> If you have devised a method of handling events
> other than mice and keyboards I would appreciate
> a tour of the code so I may integrate my touch screen
> applications into the Xforms world.
>
> Thanks in advance
>
> Serge

//
// This code was built on a Linux machine.
// This code is extracted and will not build by itself.
// This code is c++ code and I call several functions that you don't
// know about and I use a logfile object of my own devising (I am like
// a mad scientist when I use c++). So, just ignore these silly things.
// You should be able to track the flow of events out of their queues
// and into their dispersion functions.
//
// There is something that should be said now. fl_initialize() opens
// a display connection that is used by the forms library. I leave this
// connection to the forms library and open another display connection
// for my use with the X11, Xt, and Xm (Motif) libraries. Additionally,
// the Lockheed Sanders MCG&I system pumps its events along using my X11, Xt,
Xm
// display connection as X11 ClientMessage events. So, I deal with two
// X display connections. Also, I read from a pipe connected to a child
// process that operates as a message server.
//
// Now. You can handle any event stream in this event handler function
// if you can do so without blocking.
//

//
// handlewaitingevents() will allow you to intersperse event handling with
// lengthy operations and will allow you to construct "local" event loops.
// This is a very important thing to be able to do.
//

inline
void handlewaitingevents()
{
maineventloop( 1 );
}

//
// maineventloop() is the one function that handles all events. These events

// may be Forms Library events, X11 events, Xt events, socket activity, pipe
// activity, or anything else that does not block. Nothing can block!
Blocking
// is evil! AAAH! Actually, sleeping is allowed. Short naps only.
//

void maineventloop( char handlewaiting = 0 );

void maineventloop (

char handlewaiting )
{
// xl
int xl_nxe;
XEvent xl_xe;

// xt
XtInputMask xt_im;
XEvent xt_xe;

// mds
mdsAnyEvent * mds_anyevent;

// xf
FL_OBJECT * xf_flo;
XEvent xf_xe;

// select
int select_s;
int select_width;
fd_set select_readfds;
timeval select_timeout;

// unclassified
short int eventobserved;

const char * fnnm = "maineventloop(): ";

// - - - -

if
(
( apln_x11_display == 0 )
||
( apln_xforms_display == 0 )
||
( apln_mcgi_serverhandle == 0 )
)
{
// We are not ready to be here.
return;
}

select_width = apln_rcvmsgsrv_inpipe + 1;

while ( 1 )
{
if ( handlewaiting )
{
// We will flush all event queues now as our idle flush will not
work
// for this case.

XFlush( apln_x11_display );
XFlush( apln_xforms_display );
mdsFlush( apln_mcgi_serverhandle );
}

eventobserved = 0;

//----------------------------------------------------------------------
// Look for an overlay builder canvas event.
// We are handling these events.

if ( apln_ctafsforms_createeditoverlaywin != 0 )
{
// #define QueuedAlready 0
// #define QueuedAfterReading 1
// #define QueuedAfterFlush 2
xl_nxe = XEventsQueued( apln_x11_display, QueuedAfterFlush );
if ( xl_nxe > 0 )
{
XPeekEvent( apln_x11_display, & xl_xe );
if
(
( xl_xe.xany.window == ovlybldr_iconcanvas_window )
||
( xl_xe.xany.window == ovlybldr_objectpreview_window )
)
{
#if 0
logfile << "XPeekEvent found an overlay builder canvas
event on the
Xt display connection.\n" << hflush();
#endif
XNextEvent( apln_x11_display, & xl_xe );
if ( xl_xe.xany.window == ovlybldr_iconcanvas_window )
ovlybldr_iconcanvashandler_xl( xl_xe );
else
if ( xl_xe.xany.window == ovlybldr_objectpreview_window )

ovlybldr_objectpreviewcanvashandler_xl( xl_xe );
else;
eventobserved ++ ;
} // Overlay builder canvas event
} // if ( xl_nxe > 0 )
} // if ( apln_ctafsforms_createeditoverlaywin != 0 )

//----------------------------------------------------------------------
// Attempt to receive an X event from our Xt event queue.
// MCG&I events will use this queue also.

xt_im = XtAppPending( apln_x11_appcontext );

if (( xt_im & XtIMTimer ) || ( xt_im & XtIMAlternateInput ))
{
XtAppProcessEvent( apln_x11_appcontext, XtIMTimer |
XtIMAlternateInput );
eventobserved ++ ;
} // if (( xt_im & XtIMTimer ) || ( xt_im & XtIMAlternateInput ))

if ( xt_im & XtIMXEvent )
{
XtAppNextEvent( apln_x11_appcontext, & xt_xe );
mds_anyevent = (mdsAnyEvent *) & xt_xe;

if
(
( xt_xe.type == ClientMessage )
&&
( mds_anyevent->message_type == apln_mcgi_evtyat_mdsError )
)
{
mdsErrorEvent * mds_errorevent = (mdsErrorEvent *) & xt_xe;

logfile
<< "\n\n"
<< "B * O * I * N * G * O ----> MCGI error event
caught!\n"
<< writeNV( mds_errorevent->error_code ) << "\n"
<< writeNV( mds_errorevent->request_code ) << "\n"
<< writeNV( mds_errorevent->minor_code ) << "\n"
<< "\n\n" << hflush();

hbell_warning2();
}
else
if
(
apln_mcgi_ready
&&
( xt_xe.type == ClientMessage )
&&
mdsDispatchEvent( apln_mcgi_serverhandle, (mdsEvent *)( &
xt_xe ))
)
{
#if 1
logfile << "Called mdsDispatchEvent().\n" << hflush();
#endif
}
else
if
(
xt_xe.xany.window == apln_MW_rootwindowpixmap_window
)
{
rootwindoweventhandler( xt_xe );
}
else
{
XtDispatchEvent( & xt_xe );
}
eventobserved ++ ;
} // if ( xt_im & XtIMXEvent )

//----------------------------------------------------------------------
// Handle CTAFS UI R MSG events.

if ( eventobserved == 0 )
{
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 0;
FD_ZERO( & select_readfds );
FD_SET( apln_rcvmsgsrv_inpipe, & select_readfds );

select_s = select( select_width, & select_readfds, (fd_set *)0,
(fd_set
*)0, & select_timeout );

if ( select_s < 0 )
{
// Error, ignore.
}
else
if ( select_s == 0 )
{
// No descriptors are ready, do nothing.
}
else
{
// Some descriptors are ready.
ctafsrmsg_receivemessage( select_s, select_readfds );
eventobserved ++ ;
}
} // R message event handling

//----------------------------------------------------------------------
// Handle X Forms Library events.

// We only handle Forms Library events if we know there are no
other events
// waiting to be handled. This is because I have found the
fl_check_forms()
// function to be a big huge hog!
if ( eventobserved == 0 )
{
xf_flo = fl_check_forms();

if ( xf_flo == FL_EVENT )
{
logfile << fnnm << "fl_check_forms() returned FL_EVENT.\n" <<
hflush();

fl_XNextEvent( & xf_xe );
eventobserved ++ ;
}
else
if ( xf_flo != NULL )
{
logfile << fnnm << "Observed an XForms event.\n" << hflush();

apln_xforms_mcf_flo = xf_flo;
eventobserved ++ ;
}
else;
} // Forms Library event handling

//----------------------------------------------------------------------
// If no events have been observed and we are here to just handle
// waiting events, then exit this function.

if ( handlewaiting && ( eventobserved == 0 ))
{
break;
}

//----------------------------------------------------------------------
// Exit point.

if (( ! handlewaiting ) && apln_evhn_timetoquit )
{
break;
}

//----------------------------------------------------------------------
// Sleep if low activity.

if ( eventobserved == 0 )
{
XFlush( apln_x11_display );
XFlush( apln_xforms_display );
mdsFlush( apln_mcgi_serverhandle );

usleep( /* unsigned long __usec */ 1000 );
} // Low activity sleep
} // Event loop
}

--
  (Stephen Huyssoon)
>=============================>
  (huyssoons@advancia.com)                            www.advancia.com

To Infinity and Beyond! -- Me and Buzz Lightyear

The Truth cannot be proven nor disproven, it simply Is.

Derick's Writ of Habeas Corpus: Ok, back on your heads!

_________________________________________________ To unsubscribe, send the message "unsubscribe" to xforms-request@bob.usuhs.mil or see http://bob.usuhs.mil/mailserv/xforms.html XForms Home Page: http://bragg.phys.uwm.edu/xforms List Archive: http://bob.usuhs.mil/mailserv/list-archives/