/* Events Notification Server Library Interface */!!

inherit(ProvidedLibs, #EvNoteLib, nil, 2, nil)!!

now(class(EvNoteLib))!!

/* semiPRIVATE -- should only be called via require(MallocLib)
   Define entry points and load library.  Define any structs required.
*/
Def provide(self, path)
{
  ^initialise( new(self:ancestor), path )
    
/*  ^initialise( new(self:ancestor), "enlib.dll" ) */
}
!!

now(EvNoteLib)!!

/* 6/12/1992 14:59 - PUBLIC 
   UNREGISTER with Event Notification Library for events opened
   in initEvent():
   And clear out the eventRespSet[...].     
*/
Def closeEvents(self, eventDescSet )
{
  if eventDescSet then
    do(eventDescSet,
    {using(eventDescriptor)
      unRegister(self, eventDescriptor ) ;
    });
  endif ;
  eventDescSet := nil;
}
 
!!

/* 6/12/1992 14:36 - PUBLIC
  register the events with Event Notitification Lib.
  Return the set of registered Event Descriptor, or nil if error.
  EX: eventDescSet := registerEvents(EvNoteLibClass$Inst, hWnd, tuple(EVENT_CPU_PC_CHANGED, ...));
*/
Def registerEvents(self, registerWnd, events | eventDesc, eventDescSet )
{ 
  if not(events) or not(registerWnd) then
    ^nil;
  endif;  
  /* Allocate new set to store event registered */
  eventDescSet := new(Set, size(events));

  do(events,
  {using(event)
    if eventDesc := register(self, event, registerWnd ) then 
      add(eventDescSet, eventDesc ) ;
    endif ;
  });    

  /* Return the descriptors set */  
  ^eventDescSet;    
}
!!

/* PRIVATE
   Define all entry points for library as prototypes.
*/
Def addImportProcs(self)
{
  add(self, #INITCSERVER,    1, #(0, 0));
  add(self, #ENLREGISTERWIN, 1, #(1, 0, 1));
  add(self, #ENLREGISTER,    1, #(1, 1, 1)); /* callback */
  add(self, #ENLUNREGISTER,  1, #(1));
  add(self, #ENLEVENTNOTIFY, 1, #(1));
}
!!

/* PRIVATE 
   Open and initialize Event Notification server library
*/
Def initialise(self, path)
{
   setName( self, path ) ;
   addImportProcs( self ) ;
   if not( UserMessages )
   then
     add( Actor, #UserMessages, new(Dictionary, 64) ) ;
   endif ;
     add(UserMessages, EVENT_MSG, #WM_EVENT) ; /* for event notification */

/* defineStructs( self ) ; */
   load( self ) ;  /* raises alert if fails: alert(System, self, #libLoad) */
}
!!

/* PUBLIC -- register window with server on event
   Return EventID or nil.
*/
Def notify(self, event)
{ 
  if pcallLock(self)
  then
    lastError := pcall( procs[#ENLEVENTNOTIFY], event ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;
  if (lastError <> GOOD)
     displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
  endif;
  ^lastError;
}
!!

/* PUBLIC -- register window with server on event
   Return EventID or nil.
*/
Def register(self, eventWanted, hWND | evIDref)
{ 
  evIDref := new( Struct, 4 ) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#ENLREGISTERWIN], eventWanted, hWND, evIDref ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;

  if (lastError = GOOD) then
     ^longAt( evIDref, 0 )
  endif;
  displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
  ^nil;
}
!!

/* PUBLIC -- register window with server on event
   Return EventID or nil. 
   N.b.: caller must lock callback.
*/
Def registerCallback(self, eventWanted, callback | evIDref)
{ 
  evIDref := new( Struct, 4 ) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#ENLREGISTER], eventWanted, callback, evIDref ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;

  if (lastError = GOOD) then
    ^longAt( evIDref, 0 )
  endif;
  displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
  ^nil
}
!!

/* PUBLIC -- Unregister window on event */
Def unRegister(self, eventID)
{ 
  if pcallLock(self)
  then
    lastError := pcall( procs[#ENLUNREGISTER], eventID ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;

  if (lastError <> GOOD) then
     displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
     ^nil
  endif;
  ^lastError;
}
!!
