/* * Ivy League * * Xt-based multiplexers/schedulers * * Copyright 1993-2000 * Centre d'Etudes de la Navigation Aerienne (CENA) * * code by Stephane Chatty * * $Id$ * */ #include "XtMultiplexer.h" #include "error.h" IvlXtMultiplexer :: IvlXtMultiplexer () : IvlBaseMultiplexer () { memset (ReadId, 0, NFILE * sizeof (XtInputId)); memset (WriteId, 0, NFILE * sizeof (XtInputId)); } IvlXtMultiplexer :: ~IvlXtMultiplexer () { } /* the input and output callback for channels */ static void inputCB (XtPointer client_data, int*, XtInputId*) { IvlChannel* chan = (IvlChannel*) client_data; chan->HandleRead (); } static void outputCB (XtPointer client_data, int*, XtInputId*) { IvlChannel* chan = (IvlChannel*) client_data; chan->HandleWrite (); } void IvlXtMultiplexer :: SetMasks (int fd, IOMODE mode) { IvlChannel* ch = Channels [fd]; if (!ch) return; /* remove if already there */ if (ReadId [fd]) { XtRemoveInput (ReadId [fd]); ReadId [fd] = (XtInputId) 0; ReadCount--; } if (WriteId [fd]) { XtRemoveInput (WriteId [fd]); WriteId [fd] = (XtInputId) 0; WriteCount--; } /* add channel */ if (mode & IORead) { ReadId [fd] = XtAddInput (fd, (XtPointer) XtInputReadMask, inputCB, (caddr_t) ch); ReadCount++; } if (mode & IOWrite) { WriteId [fd] = XtAddInput (fd, (XtPointer) XtInputWriteMask, outputCB, (caddr_t) ch); WriteCount++; } if (mode & IOSelect) Error (ErrWarn, "AddChannel", "select condition ignored"); } void IvlXtMultiplexer :: FireTimers (void* mpx, XtIntervalId*) { IvlCoreTimer::Fire (((IvlXtMultiplexer*) mpx)->GetTimerSet ()); } void IvlXtMultiplexer :: SetTimeOut (Millisecond delay) { /* should replace with XtAppAddTimeOut */ TimeOut = XtAddTimeOut (delay, &IvlXtMultiplexer::FireTimers, this); } void IvlXtMultiplexer :: SuppressTimeOut () { XtRemoveTimeOut (TimeOut); TimeOut = 0; } void IvlXtMultiplexer :: FireSignals (void* mpx) { ((IvlXtMultiplexer*) mpx)->HandleDeferredSignals (); } void IvlXtMultiplexer :: AddSignalHook () { /* should replace with XtAppAddWorkProc */ XtAddWorkProc ((XtWorkProc) (&IvlXtMultiplexer::FireSignals), this); } MPX_RES IvlXtMultiplexer :: Loop () { XEvent event; bool waiting = true; while (Looping && (waiting || ReadCount || WriteCount)) { // *** problem with other loop: work proc are not called! // *** we must find a way to exit properly with this one... // *** sending ourselves an event??? XtNextEvent (&event); XtDispatchEvent (&event); if (ReadCount || WriteCount) waiting = false; } if (Looping) { Looping = false; return isMpxEmpty; } return isMpxTerminated; }