#ifndef _APERIODICHANDLER_H
#define _APERIODICHANDLER_H
static char AperiodicHandler_h_id[] = "$Header: /usr/tiburon/unix/gui/tmacs/RCS/AperiodicHandler.h,v 1.6 1997/10/03 09:38:22 oreilly Exp $";

/*
$Log: AperiodicHandler.h,v $
Revision 1.6  1997/10/03 09:38:22  oreilly
*** empty log message ***

 * Revision 1.5  97/03/20  12:32:48  12:32:48  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.4  96/10/28  09:13:22  09:13:22  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.3  96/10/18  14:15:38  14:15:38  oreilly (Thomas C. O'Reilly)
 * Using workprocs to read input pipe
 * 
*/

#include <unistd.h>
#include "SList.h"
#include "DmMonitor.h"
#include "DmGuiObject.h"
#include "RegisteredItem.h"

#define NoInput MAXLONG

class AperiodicHandler;

/*
RegisteredDmItem describes a DM item registered with AperiodicHandler
*/
class RegisteredDmItem : public RegisteredItem
{
  friend class AperiodicHandler;

  public:
  RegisteredDmItem(const char *name, DM_Item handle);

  ~RegisteredDmItem()
  {
    free(_itemName);
  }

  // Terminate child process, remove semaphore
  int cleanup();
  
  private:  

  char *_itemName;
  DM_Item _handle;
};


class DmGuiApp;

/*
AperiodicHandler maintains list of DmItems to be read aperiodically;
invokes updateGui() method of appropriate DmGuiObject(s) when new
aperiodic data arrives */
class AperiodicHandler
{
  friend class DmGuiApp;
  
  public:
  AperiodicHandler();
  ~AperiodicHandler();
  
  /* Register DM item and associated GUI(s) */
  registerObj(DmGuiObject *guiObj);
  
  /* Unregister DM item */
  unregisterObj(DmGuiObject *);

  /* Start handler */  
  void start();
  
  protected:

  SList<RegisteredDmItem *> _dmItemList;

  XtInputId _inputId;

  // File descriptor for writing requests to DM Monitor process
  int _writePipe;

  // File descriptor for receiving data notification from DM Monitor process
  int _readPipe;

  // Pid of monitor process
  pid_t _monitorPid;
  
  // ID of monitor semaphore
  SEM_ID _monitorSem;

  // Process notification messages in pipe
  Boolean processNewData();

  // Get pointer to DmGuiApp
  static DmGuiApp *getDmGuiApp(); 
  int writeRequest(RequestMessage *request);

  // Clean up child process and IPC stuff
  int cleanup();
  
  private:
  
  // dataReadyCallback() is called data is ready for a DM consumer
  static void dataReadyCallback(XtPointer clientData, int *fid, 
				XtInputId *id);
  
  static Boolean newDataWorkProc(XtPointer clientData);
};


#endif
