/****************************************************************************
**
**  Name:  enlib.c
**
**  Description:
**     Event Notification Library for registering/unregistering and
**     notification of all events in the system.  An event can be anything
**     that happens (emulation stopped, communications failed, etc.).
**     See enlib.h for list of events.
**
**  Status:  TESTED
**
**  $Log:   S:/tbird/arcppc/enlib/enlib.c_v  $
** 
**    Rev 1.0   17 Jan 1997 09:13:08   kevin
** Initial revision.
** 
**    Rev 1.0   03 Jun 1996 11:21:34   gene
** Initial revision.
** 
**    Rev 1.0   07 Sep 1995 10:18:28   gene
** Initial revision.
** 
**    Rev 1.28   05 Oct 1993 10:51:48   nghia
** Revised EVENT_CLI_CMD_COMPLETE to EVENT_CLI_COMMAND_COMPLETE
** Added EVENT_STK_BASE_SIZE_AVAIL for event text.
** 
**    Rev 1.27   13 Jul 1993 20:22:02   doug
** Errors consolidated in errtext/mkerrors.h and use generic syntax error
** 
**    Rev 1.26   13 Jul 1993 09:35:06   ernie
** Added event EVENT_LDR_MEMCHANGED
** 
**    Rev 1.25   28 Jun 1993 10:58:52   ron
** changed MessageBox to ErrMessageBox and added corresponding Help button
** and help entry.
** 
**    Rev 1.24   10 Jun 1993 13:05:36   steveh
** remove low level breakpoints (no longer used) and add missing events.
** 
**    Rev 1.23   23 Nov 1992 12:11:52   doug
** a) remove macros for memory allocation
** b) ppr7690 fixed: allow cli command complete events to get through
** c) also, if there are events in the fifo, allows these through
** 
**    Rev 1.22   06 Nov 1992 13:40:10   doug
** added 2 missing events and clarified what file to change when events added
** to system
** 
**    Rev 1.21   08 Sep 1992 15:19:20   doug
** Include events.h; use new event definitions.
** 
**    Rev 1.20   29 Aug 1992 21:43:16   brucea
** Added: 2 new memory events to GetEventText
** 
**    Rev 1.19   29 Aug 1992 07:25:32   doug
** go back to post message since this causes multi-tasking problems.  Instead,
** we are going to flush the message queue at the beginning of each CLI
** command and before emulation starts.
** 
**    Rev 1.18   27 Aug 1992 13:34:22   doug
** added query feature
** 
**    Rev 1.17   27 Aug 1992 11:14:24   doug
** Use send message now that Actor is fixed.  This will prevent the event
** queue from overflowing.
** 
**    Rev 1.16   27 Aug 1992 06:36:14   mindy
** updated tracing events text
** 
**    Rev 1.15   25 Aug 1992 10:58:10   brucea
** Fixed: UAE in NotifyOfEvent from too small a buffer when in debug mode
** Added: two trace events to GetEventText
** 
**    Rev 1.14   19 Aug 1992 07:19:48   doug
** added new cpu events
** 
**    Rev 1.13   14 Aug 1992 08:02:52   doug
** array indices can only be size int
** 
**    Rev 1.12   14 Aug 1992 07:37:02   doug
** remove warnings now that strict checking is enables (still have one type
** I do not understand yet)
** 
**    Rev 1.11   12 Aug 1992 08:20:40   doug
** show event number when displaying callback and windows since they are
** queued up and do not necessarily come directly after the event
** 
**    Rev 1.10   11 Aug 1992 09:25:12   doug
** added event debug command and support
** 
**    Rev 1.9   08 Aug 1992 09:43:48   tom
** new server registration changes
** 
**    Rev 1.8   20 May 1992 11:27:48   mindy
** initCServer needs to return GOOD if no errors
** 
**    Rev 1.7   14 May 1992 11:56:44   mindy
** removed get error text routine
** 
**    Rev 1.6   13 May 1992 10:38:56   mindy
** a) use global errors for memory allocation and lock.
** b) added get error text routine.
** 
**    Rev 1.5   07 May 1992 11:31:38   courtney
** Fixed bug regarding reallocation of Fifo queue (was incorrectly passing
** handle to event queue).  Also, general cleanup (standard error codes with
** TBird module id, HANDLE not HWND for memory handles).
** 
**    Rev 1.4   19 Mar 1992 12:02:16   doug
** a) added CLI interface for debug command "notify" to turn notification
**    on and off.  If someone suspects there is a problem with event
**    notification, this will be an easy way to disable it.
** b) changed error messages to conform to standard.
** 
**    Rev 1.3   07 Feb 1992 07:12:22   doug
** use PostMessage to correct bug in Actor.  When an Actor window is registered,
** when it is notified, if it calls a server, the system crashes.  This is
** because the C stack Actor uses is not re-entrant.  Whitewater is fixing
** this problem.  By using PostMessage, the event notification will exit
** C and then the Actor routines will start... avoiding the re-entrancy
** problem.
** 
**    Rev 1.2   08 Nov 1991 14:30:18   doug
** when event reallocation occurs, the number of event entries must be
** incremented (caused endless re-allocation error and a UAE)
** 
**    Rev 1.1   08 Nov 1991 13:17:02   doug
** First version tested with wintest.exe.
** 
**    Rev 1.0   06 Nov 1991 11:12:46   doug
** Initial revision.
** 
**  $Header:   S:/tbird/arcppc/enlib/enlib.c_v   1.0   17 Jan 1997 09:13:08   kevin  $
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#ifndef _BASEWIND_
#include "basewind.h"
#endif
#ifndef _BKPTEXEC_
#include "bkptexec.h"
#endif
#ifndef _CLISRV_
#include "clisrv.h"
#endif
#ifndef _CPU_
#include "cpu.h"
#endif
#ifndef _ENLIB_
#include "enlib.h"
#endif
#ifndef _HEAP_
#include "heap.h"
#endif
#ifndef _HOSTERRS_
#include "hosterrs.h"
#endif
#ifndef _LDRSVR_
#include "ldrsvr.h"
#endif
#ifndef _PMEM_
#include "pmem.h"
#endif
#ifndef __STDIO_H
#include "stdio.h"
#endif
#ifndef _STKSERVR_
#include "stkservr.h"
#endif
#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif
#ifndef __STRING_H
#include "string.h"
#endif
#ifndef _TBIRDMEM_
#include "tbirdmem.h"
#endif
#ifndef _TRACE_
#include "trace.h"
#endif
#ifndef _VARSERVR_
#include "varservr.h"
#endif
#ifndef _EVENTS_
#include "events.h"
#endif
#ifndef _HLPENTRY_
#include "hlpentry.h"
#endif

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
HANDLE cliServerHandle = (HANDLE)NULL;  /* force definition here */

typedef enum { NOT_IN_USE, EVENT_CALLBACK, EVENT_WINHANDLE } EVENT_TYPE;

typedef struct {
   EVENT_TYPE type; /* type of event or not in use */
   U32 event; /* event number this callback/handle is registered on */
   EVCALLBACK callback; /* function to call if type EVENT_CALLBACK */
   HWND winHandle; /* handle of window to send message if type
                      EVENT_WINHANDLE */
} EVENT;

#define NUM_EVENT_INCREMENT 20 /* number of entries to expand by each time */
#define EVENT_WFLAGS (GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_ZEROINIT)
                     /* how event memory is allocated */

PRIVATE U32 numEventEntries = 0; /* number of entries in event table */
PRIVATE HANDLE hEvent = NULL; /* event descriptor array memory */

#define NUM_FIFO_INCREMENT 20 /* number of entries to expand by each time */
#define FIFO_WFLAGS (GMEM_MOVEABLE|GMEM_NODISCARD) /* allocation type */

PRIVATE U16 numFifoEntries = 0; /* number in fifo table */
PRIVATE U16 numFifoActive = 0; /* number in use in fifo table */
PRIVATE HANDLE hFifo = NULL; /* fifo for pending event numbers */
#define FifoEmpty() (numFifoActive==0)

BOOLEAN eventNotifyActive = TRUE;
BOOLEAN eventDebug = FALSE;
BOOLEAN eventQuery = FALSE;

                        /****************************
                         *                          *
                         *    EXTERNAL VARIABLES    *
                         *                          *
                         ****************************/

                        /****************************
                         *                          *
                         *     LOCAL PROTOTYPES     *
                         *                          *
                         ****************************/
RETCODE PRIVATE CommonRegister(U32 event, HWND winHandle,
                       EVCALLBACK callback, DESCRIPTOR FAR *desc);
RETCODE PRIVATE AddToFifo(U32 event);
RETCODE PRIVATE GetFirstFifoEvent(U32 *event);
RETCODE PRIVATE NotifyOfEvent(U32 event);
RETCODE PRIVATE RemoveFirstFifoEvent(VOID);
RETCODE PRIVATE SendCliMessage(HANDLE cliHandle, LPSTR msgPtr);
VOID PRIVATE GetEventText(U32 event, S8 *buff);

                        /****************************
                         *                          *
                         *      EXECUTABLE CODE     *
                         *                          *
                         ****************************/
/***************************************************************************
**
** EnlRegisterWin
**
****************************************************************************/
RETCODE EXPORT EnlRegisterWin(U32 event, HWND winHandle,
                              DESCRIPTOR FAR *desc){
   return(CommonRegister(event, winHandle, NULL, desc));
}

/***************************************************************************
**
** EnlRegister
**
****************************************************************************/
RETCODE EXPORT EnlRegister(U32 event, EVCALLBACK callback,
                           DESCRIPTOR FAR *desc) {
   return(CommonRegister(event, 0, callback, desc));
}

/***************************************************************************
**
** EnlEventNotify
**
****************************************************************************/
RETCODE EXPORT EnlEventNotify(U32 event) {
   RETCODE err;
   S16 response;

   if(eventDebug) {
      S8 buff[80];
      GetEventText(event, buff);
      SendCliMessage(cliServerHandle, (LPSTR)buff);
   }
   if((eventNotifyActive==FALSE) && (event!=EVENT_CLI_COMMAND_COMPLETE) &&
      (FifoEmpty())) return(GOOD);
   if(eventQuery) {
      S8 buff[80];
      S8 buff1[256];
      GetEventText(event, buff);
      wsprintf(buff1, "Allow %s?", buff);
      ErrMessageBox((LPSTR) "Enlib Debug Query", 
         (LPSTR) buff1, MB_YESNO, HE_ENLIB_DEBUG_QUERY_1, 
         (S16 FAR *) &response);
      switch(response) {
         case IDNO: return(GOOD);
         case IDYES: break;
         default:
            SendCliMessage(cliServerHandle,
               (LPSTR)"Error bringing up enlib query message box");
            break;
      }
   }
   if(hEvent==NULL) return(GOOD); /* no one is registered */
   if(!FifoEmpty()) { /* already doing notification, add to fifo */
      if((err = AddToFifo(event))!=GOOD) return(err);
   } else {
      U32 currentEvent;
      if((err = AddToFifo(event))!=GOOD) return(err);
      while(numFifoActive!=0) { /* while not empty */
         if((err = GetFirstFifoEvent(&currentEvent))!=GOOD) return(err);
         if((err = NotifyOfEvent(currentEvent))!=GOOD) return(err);
         if((err = RemoveFirstFifoEvent())!=GOOD) return(err);
      }
   }
   return(GOOD);
}

/***************************************************************************
**
** EnlUnRegister
**
****************************************************************************/
RETCODE EXPORT EnlUnRegister(DESCRIPTOR desc) {
   EVENT *ev;
   if((ev = (EVENT *)GlobalLock(hEvent))==NULL)
      return(ER_WINDOWS_MEMLOCK);
   ev[(int)desc].type = NOT_IN_USE;   
   GlobalUnlock(hEvent);
   return(GOOD);
}

/***************************************************************************
**
** CommonRegister
**
****************************************************************************/
RETCODE PRIVATE CommonRegister(U32 event, HWND winHandle,
                       EVCALLBACK callback, DESCRIPTOR FAR *desc) {
   EVENT *ev;
   HANDLE hEvent1;
   LOOP_VAR i;
   
   if(hEvent==NULL) { /* if table never created, do so */
      if((hEvent = GlobalAlloc(EVENT_WFLAGS,
                        NUM_EVENT_INCREMENT*sizeof(EVENT)))==NULL)
         return(ER_OUT_OF_MEMORY);
      numEventEntries += NUM_EVENT_INCREMENT;
   }
   if((ev = (EVENT *)GlobalLock(hEvent))==NULL)
       return(ER_WINDOWS_MEMLOCK);
   for(i=0; i<numEventEntries; i++) {
      if(ev[i].type==NOT_IN_USE) {
         ev[i].type = (callback==NULL)?EVENT_WINHANDLE:EVENT_CALLBACK; 
         ev[i].event = event; 
         ev[i].callback = callback; 
         ev[i].winHandle = winHandle;
         *desc = i;  /* use the index as the descriptor */
         GlobalUnlock(hEvent);
         return(GOOD);
      }
   }
   /*
   ** the entire table is in use, expand it and try again
   */
   if((hEvent1 = GlobalReAlloc(hEvent,
          (numEventEntries+NUM_EVENT_INCREMENT)*sizeof(EVENT),
          EVENT_WFLAGS))==NULL) return(ER_OUT_OF_MEMORY);
   hEvent = hEvent1;
   numEventEntries += NUM_EVENT_INCREMENT;
   return(CommonRegister(event, winHandle, callback, desc));
}

/***************************************************************************
**
** AddToFifo
**
****************************************************************************/
RETCODE PRIVATE AddToFifo(U32 event) {
   U32 *fifo;
   if(hFifo==NULL) {
      if((hFifo = GlobalAlloc(FIFO_WFLAGS,
                        NUM_FIFO_INCREMENT*sizeof(U32)))==NULL)
         return(ER_OUT_OF_MEMORY);
      numFifoEntries += NUM_FIFO_INCREMENT;
   } else if(numFifoActive==numFifoEntries) {
      HANDLE hFifo1;
      /*
      ** the entire table is in use, expand it and try again
      */
      if((hFifo1 = GlobalReAlloc(hFifo,
             (numFifoEntries+NUM_FIFO_INCREMENT)*sizeof(U32),
             FIFO_WFLAGS))==NULL) return(ER_OUT_OF_MEMORY);
      hFifo = hFifo1;
      numFifoEntries += NUM_FIFO_INCREMENT;
   }
   /*
   ** add event to the end of the fifo
   */
   if((fifo = (U32 *)GlobalLock(hFifo))==NULL)
      return(ER_WINDOWS_MEMLOCK);
   fifo[numFifoActive++] = event;
   GlobalUnlock(hFifo);
   return(GOOD);
}

/***************************************************************************
**
** GetFirstFifoEvent
**
****************************************************************************/
RETCODE PRIVATE GetFirstFifoEvent(U32 *event) {
   U32 *fifo;
   if((fifo = (U32 *)GlobalLock(hFifo))==NULL)
         return(ER_WINDOWS_MEMLOCK);
   *event = fifo[0];
   GlobalUnlock(hFifo);
   return(GOOD);
}

/***************************************************************************
**
** NotifyOfEvent
**
****************************************************************************/
RETCODE PRIVATE NotifyOfEvent(U32 event) {
   EVENT *ev;
   LOOP_VAR i;
   S16 response;
   if((ev = (EVENT *)GlobalLock(hEvent))==NULL)
      return(ER_WINDOWS_MEMLOCK);
   for(i=0; i<numEventEntries; i++) {
      if((ev[i].type!=NOT_IN_USE) && (ev[i].event==event)) {
         S8 buff[120], eventText[80];
         if(ev[i].type==EVENT_CALLBACK) {
            if(eventDebug) {
               GetEventText(event, eventText);
               sprintf(buff, "   *** notify callback %p (%s) ***",
                  ev[i].callback, eventText);
               SendCliMessage(cliServerHandle, (LPSTR)buff);
            }
            if(eventQuery) {
               GetEventText(event, eventText);
               sprintf(buff, "Allow   *** notify callback %p (%s) *** ?",
                  ev[i].callback, eventText);
               ErrMessageBox((LPSTR) "Enlib Debug Query", 
                  (LPSTR) buff, MB_YESNO, HE_ENLIB_DEBUG_QUERY_2, 
                  (S16 FAR *) &response);
               switch(response) {
                  case IDNO: continue;
                  case IDYES: break;
                  default:
                     SendCliMessage(cliServerHandle,
                        (LPSTR)"Error bringing up enlib query message box");
                     break;
               }
            }
            ev[i].callback(event);
         } else {
            if(eventDebug) {
               GetEventText(event, eventText);
               sprintf(buff, "   *** notify window %d (0x%04x) (%s) ***",
                  ev[i].winHandle, ev[i].winHandle, eventText);
               SendCliMessage(cliServerHandle, (LPSTR)buff);
            }
            if(eventQuery) {
               GetEventText(event, eventText);
               sprintf(buff, "Allow   *** notify callback %p (%s) *** ?",
                  ev[i].callback, eventText);
               ErrMessageBox((LPSTR) "Enlib Debug Query", 
                  (LPSTR) buff, MB_YESNO, HE_ENLIB_DEBUG_QUERY_3, 
                  (S16 FAR *) &response);
               switch(response) {
                  case IDNO: continue;
                  case IDYES: break;
                  default:
                     SendCliMessage(cliServerHandle,
                        (LPSTR)"Error bringing up enlib query message box");
                     break;
               }
            }
            PostMessage(ev[i].winHandle, EVENT_MSG, NULL, event);
         }
      }
   }
   GlobalUnlock(hEvent);
   return(GOOD);
}

/***************************************************************************
**
** RemoveFirstFifoEvent
**
****************************************************************************/
RETCODE PRIVATE RemoveFirstFifoEvent(VOID) {
   U32 *fifo;
   LOOP_VAR i;
   if((fifo = (U32 *)GlobalLock(hFifo))==NULL)
      return(ER_WINDOWS_MEMLOCK);
   for(i=0; i<numFifoActive-1; i++)
      fifo[i] = fifo[i+1]; /* move all entries down one */
   numFifoActive--;
   GlobalUnlock(hFifo);
   return(GOOD);
}

/**************************************************************************
**
** InitCServer
**
***************************************************************************/
RETCODE EXPORT InitCServer(HANDLE cliHandle, HANDLE dllHandle) {
   CSERVER_NEW_REGISTRATION FAR * msgBufPtr;

   cliServerHandle = cliHandle;
   msgBufPtr =
      (CSERVER_NEW_REGISTRATION FAR *)TMalloc(sizeof(CSERVER_VARIABLE_VALUE));
   if (msgBufPtr == NULL) {
      return(ER_OUT_OF_MEMORY);
   }

   msgBufPtr->stringResourceHandle = dllHandle;

   msgBufPtr->serverNameIndex = 30;
   msgBufPtr->dllNameIndex = 31;
   msgBufPtr->numberOfCommandsIndex = 32;
   msgBufPtr->commandStartIndex = 33;
   SendMessage(cliHandle, CLI_NEW_SVR_REGISTRATION, CLI_NEW_SVR_REGISTRATION,
      (DWORD)msgBufPtr);
   return(GOOD);
}

RETCODE PRIVATE SendCliMessage(HANDLE cliHandle, LPSTR msgPtr) {
   HANDLE msgBufHandle;
   CSERVER_RESULTS FAR  *msgBufPtr;
   U16         msgTextSize, loop ;

   msgTextSize = lstrlen(msgPtr);
   if ((msgBufHandle = GlobalAlloc(GMEM_MOVEABLE, sizeof(CSERVER_RESULTS) + msgTextSize + 1)) == NULL) {
      return(ER_OUT_OF_MEMORY);  /* FAILED */
   }
   else if((msgBufPtr=(CSERVER_RESULTS *)GlobalLock(msgBufHandle)) == NULL) {
      return(ER_WINDOWS_MEMLOCK) ; /* FAILED */
   }
   msgBufPtr->target               = 0;
   msgBufPtr->variantCode          = CLI_SERVER_RESULTS;
   msgBufPtr->resultTextLength     = msgTextSize; /* message string length */
   for (loop = 0; loop < msgTextSize; loop++ ) {
      msgBufPtr->messageText[loop]  =  *msgPtr++;
   }
   msgBufPtr->messageText[msgTextSize]  =  '\0' ;

   /* output message to memBufPtr->messageText[] */
   GlobalUnlock(msgBufHandle);

   if (SendMessage( cliHandle, CLI_SERVER_RESULTS, msgBufHandle,
      (DWORD)CLI_SERVER_RESULTS )) {
      return( GOOD ) ; /* Success */
   }
   else {
      return(ER_ENL_CLI) ; /* Failure */
   }
}

/***************************************************************************
**
**  EnlCliNotify
**
**  Status:  TESTED
**
**  description:
**     enl_notify [on|off] to display (no parameters) or set notification
**     on or off.
**
**  input:
**     cmdString:  input text
**     argc:  argument count
**     argv:  offsets into cmdString where arguments start
**
**  output:
**     none
**
*****************************************************************************/
RETCODE EXPORT EnlCliNotify(LPSTR cmdString, U32 argc, U32 argv[]) {

   if(argc==1) {
      /* display current setting */
      SendCliMessage(cliServerHandle, eventNotifyActive ? (LPSTR)"on":
                                                          (LPSTR)"off");
   } else if(argc==2) {
      /* set */
      if(strncmpi(&cmdString[(int)argv[1]], "on",
            strlen(&cmdString[(int)argv[1]]))==0) {
         eventNotifyActive = TRUE;
      } else if(strncmpi(&cmdString[(int)argv[1]], "off",
            strlen(&cmdString[(int)argv[1]]))==0) {
         eventNotifyActive = FALSE;
      } else return(ER_CLI_SYNTAX);
   } else return(ER_CLI_SYNTAX);
   return(GOOD);
}

/***************************************************************************
**
**  EnlCliDebug
**
**  Status:  TESTED
**
**  description:
**     enl_debug [on|off] to display (no parameters) or set debug
**     on or off.
**
**  input:
**     cmdString:  input text
**     argc:  argument count
**     argv:  offsets into cmdString where arguments start
**
**  output:
**     none
**
*****************************************************************************/
RETCODE EXPORT EnlCliDebug(LPSTR cmdString, U32 argc, U32 argv[]) {

   if(argc==1) {
      /* display current setting */
      SendCliMessage(cliServerHandle, eventDebug ? (LPSTR)"debug on":
                                                   (LPSTR)"debug off");
      SendCliMessage(cliServerHandle, eventQuery ? (LPSTR)"query on":
                                                   (LPSTR)"query off");
   } else if(argc==2) {
      /* set */
      if(strncmpi(&cmdString[(int)argv[1]], "on",
            strlen(&cmdString[(int)argv[1]]))==0) {
         eventDebug = TRUE;
         eventQuery = FALSE;
      } else if(strncmpi(&cmdString[(int)argv[1]], "off",
            strlen(&cmdString[(int)argv[1]]))==0) {
         eventDebug = FALSE;
         eventQuery = FALSE;
      } else if(strncmpi(&cmdString[(int)argv[1]], "query",
            strlen(&cmdString[(int)argv[1]]))==0) {
         eventDebug = TRUE;
         eventQuery = TRUE;
      } else return(ER_CLI_SYNTAX);
   } else return(ER_CLI_SYNTAX);
   return(GOOD);
}

VOID PRIVATE GetEventText(U32 event, S8 *buff) {
   switch(event) {
      case EVENT_CLOSE_APPLICATION:
         sprintf(buff, "EVENT_CLOSE_APPLICATION"); break;
      case EVENT_BKPT_HALTED:
         sprintf(buff, "EVENT_BKPT_HALTED"); break;
      case EVENT_BKPT_EDIT:
         sprintf(buff, "EVENT_BKPT_EDIT"); break;
      case EVENT_HL_BKPTEXEC_EMUL_STARTED:
         sprintf(buff, "EVENT_HL_BKPTEXEC_EMUL_STARTED"); break;
      case EVENT_HL_BKPTEXEC_EMUL_STEPPING:
         sprintf(buff, "EVENT_HL_BKPTEXEC_EMUL_STEPPING"); break;
      case EVENT_CPU_HALTED:
         sprintf(buff, "EVENT_CPU_HALTED"); break;
      case EVENT_CPU_EDIT:
         sprintf(buff, "EVENT_CPU_EDIT"); break;
      case EVENT_CPU_PC_EDIT:
         sprintf(buff, "EVENT_CPU_PC_EDIT"); break;
      case EVENT_CPU_SP_EDIT:
         sprintf(buff, "EVENT_CPU_SP_EDIT"); break;
      case EVENT_CPU_FP_EDIT:
         sprintf(buff, "EVENT_CPU_FP_EDIT"); break;
      case EVENT_DASM_HALTED:
         sprintf(buff, "EVENT_DASM_HALTED"); break;
      case EVENT_DASM_SYM_CHANGED:
         sprintf(buff, "EVENT_DASM_SYM_CHANGED"); break;
      case EVENT_LDR_STARTPC:
         sprintf(buff, "EVENT_LDR_STARTPC"); break;
      case EVENT_LDR_STACKTOP:
         sprintf(buff, "EVENT_LDR_STACKTOP"); break;
      case EVENT_LDR_LOADCOMPLETE:
         sprintf(buff, "EVENT_LDR_LOADCOMPLETE"); break;
      case EVENT_LDR_MEMCHANGED:
         sprintf(buff, "EVENT_LDR_MEMCHANGED"); break;
      case EVENT_MAP_EDIT:
         sprintf(buff, "EVENT_MAP_EDIT"); break;
      case EVENT_MEM_HALTED:
         sprintf(buff, "EVENT_MEM_HALTED"); break;
      case EVENT_MEM_EDIT:
         sprintf(buff, "EVENT_MEM_EDIT"); break;
      case EVENT_MEM_MEMORY_CHANGED_SRC0_RANGE:
         sprintf(buff, "EVENT_MEM_MEMORY_CHANGED_SRC0_RANGE"); break;
      case EVENT_MEM_MEMORY_CHANGED_SRC1_RANGE:
         sprintf(buff, "EVENT_MEM_MEMORY_CHANGED_SRC1_RANGE"); break;
      case EVENT_STK_HALTED:
         sprintf(buff, "EVENT_STK_HALTED"); break;
      case EVENT_STK_STACK_CHANGED:
         sprintf(buff, "EVENT_STK_STACK_CHANGED"); break;
      case EVENT_STK_ALARM_OVER_LIMIT:
         sprintf(buff, "EVENT_STK_ALARM_OVER_LIMIT"); break;
      case EVENT_STK_ALARM_CHANGE:
         sprintf(buff, "EVENT_STK_ALARM_CHANGE"); break;
      case EVENT_STK_ALARM_ENABLED:
         sprintf(buff, "EVENT_STK_ALARM_ENABLED"); break;
      case EVENT_STK_ALARM_DISABLED:
         sprintf(buff, "EVENT_STK_ALARM_DISABLED"); break;
      case EVENT_STK_HWM_ENABLED:
         sprintf(buff, "EVENT_STK_HWM_ENABLED"); break;
      case EVENT_STK_HWM_DISABLED:
         sprintf(buff, "EVENT_STK_HWM_DISABLED"); break;
      case EVENT_STK_BASE_SIZE_AVAIL:
         sprintf(buff, "EVENT_STK_BASE_SIZE_AVAIL"); break;
      case EVENT_SYMBOL_INIT_LOAD:
         sprintf(buff, "EVENT_SYMBOL_INIT_LOAD"); break;
      case EVENT_SYMBOL_ONDEMAND_LOAD:
         sprintf(buff, "EVENT_SYMBOL_ONDEMAND_LOAD"); break;
      case EVENT_SYMBOL_DELETED:
         sprintf(buff, "EVENT_SYMBOL_DELETED"); break;
      case EVENT_SYMBOL_BASE_CHANGED:
         sprintf(buff, "EVENT_SYMBOL_BASE_CHANGED"); break;
      case EVENT_TRACE_CLEAR_TRACE:
         sprintf(buff, "EVENT_TRACE_CLEAR_TRACE"); break;
      case EVENT_TRACE_DEBUG_EMON:
         sprintf(buff, "EVENT_TRACE_DEBUG_EMON"); break;
      case EVENT_TRACE_NEW_SUB_BUFFER:
         sprintf(buff, "EVENT_TRACE_NEW_SUB_BUFFER"); break;
      case EVENT_TRACE_TRACING_OFF:
         sprintf(buff, "EVENT_TRACE_TRACING_OFF"); break;
      case EVENT_TRACE_TRACING_ON:
         sprintf(buff, "EVENT_TRACE_TRACING_ON"); break;
      case EVENT_TRIG_HALTED:
         sprintf(buff, "EVENT_TRIG_HALTED"); break;
      case EVENT_TRIG_TRC_BUF_NUM:
         sprintf(buff, "EVENT_TRIG_TRC_BUF_NUM"); break;
      case EVENT_VAR_HALTED:
         sprintf(buff, "EVENT_VAR_HALTED"); break;
      case EVENT_VAR_EDIT:
         sprintf(buff, "EVENT_VAR_EDIT"); break;
      case EVENT_CLI_COMMAND_COMPLETE:
         sprintf(buff, "EVENT_CLI_COMMAND_COMPLETE"); break;
      case EVENT_BKROOT_RUNACCESS_ON:
         sprintf(buff, "EVENT_BKROOT_RUNACCESS_ON"); break;
      case EVENT_BKROOT_RUNACCESS_OFF:
         sprintf(buff, "EVENT_BKROOT_RUNACCESS_OFF"); break;
      default:
         sprintf(buff, "Event 0x%08lx (no text... add to enlib.c)", event);
   }
}
/******************************** E O F ***********************************/
