/* * The Unix Channel * * by Michel Beaudouin-Lafon and Stephane Chatty * * Copyright 1990-1993 * Laboratoire de Recherche en Informatique (LRI) * Centre d'Etudes de la Navigation Aerienne * * Xt-based multiplexers * * $Id$ * $CurLog$ */ #include "XtMultiplexer.h" #include "error.h" UchXtMultiplexer :: UchXtMultiplexer () : UchBaseMultiplexer () { memset (ReadId, 0, NFILE * sizeof (XtInputId)); memset (WriteId, 0, NFILE * sizeof (XtInputId)); } UchXtMultiplexer :: ~UchXtMultiplexer () { } /* the input and output callback for channels */ static void inputCB (XtPointer client_data, int*, XtInputId*) { UchChannel* chan = (UchChannel*) client_data; chan->HandleRead (); } static void outputCB (XtPointer client_data, int*, XtInputId*) { UchChannel* chan = (UchChannel*) client_data; chan->HandleWrite (); } void UchXtMultiplexer :: SetMasks (int fd, IOMODE mode) { UchChannel* 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 UchXtMultiplexer :: FireTimers (void* mpx, XtIntervalId*) { CcuCoreTimer::Fire (((UchXtMultiplexer*) mpx)->GetTimerSet ()); } void UchXtMultiplexer :: SetTimeOut (Millisecond delay) { /* should replace with XtAppAddTimeOut */ TimeOut = XtAddTimeOut (delay, &UchXtMultiplexer::FireTimers, this); } void UchXtMultiplexer :: SuppressTimeOut () { XtRemoveTimeOut (TimeOut); TimeOut = 0; } void UchXtMultiplexer :: FireSignals (void* mpx) { ((UchXtMultiplexer*) mpx)->HandleDeferredSignals (); } void UchXtMultiplexer :: AddSignalHook () { /* should replace with XtAppAddWorkProc */ XtAddWorkProc ((XtWorkProc) (&UchXtMultiplexer::FireSignals), this); } MPX_RES UchXtMultiplexer :: 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; }