//******************************************************************************
//
//  File name   : SPSPOOL.C
//
//  Description : Make ascii file from host spool file
//
//  FUNCTIONS:
//
//
//  COMMENTS:
//
//  Copyright  (C) 1993, 1996 IBM Corporation
//                        All rights reserved.
//
//******************************************************************************

#include <windows.h>                // required for all Windows applications
#include <windowsx.h>
#include <string.h>                 // C string functions
#include <stdio.h>                  // C functions

#include "spl2file.h"               // specific to this program
#include "spdata.h"                 // Global Data
#include "dde_c.h"                  // required for PCOM DDE Appls

//******************************************************************************
//
// Local Functions
//
//******************************************************************************

void SPL_SetPsCond();    /* SF_EPSCOND    */
void SPL_GetPPs();       /* SF_GETPPS     */
void SPL_SetCsr();       /* SF_SETCSR     */
void SPL_ToTop();        /* SF_TOTOP      */
void SPL_ToLeftEnd();    /* SF_TOLEFTEND  */
void SPL_GetPs();        /* SF_GETPS      */
void SPL_IsRightEnd();   /* SF_ISRIGHTEND */
void SPL_ToRight();      /* SF_TORIGHT    */
void SPL_IsEnd();        /* SF_ISEND      */
void SPL_RollUp();       /* SF_ROLLUP     */
void SPL_AbortPend();    /* SF_ABORT      */
void SPL_Terminate();    /* SF_TERM       */

BOOL SPL_CheckItem( ATOM );

//******************************************************************************
//
// Local Data
//
//******************************************************************************

#define SPL_STATE_NO      12                      // number of states
#define SPL_EVENT_NO      8                       // number of events

#define SF_EPSCOND        0
#define SF_GETPPS         1
#define SF_SETCSR         2
#define SF_TOTOP          3
#define SF_TOLEFTEND      4
#define SF_GETPS          5
#define SF_ISRIGHTEND     6
#define SF_TORIGHT        7
#define SF_ISEND          8
#define SF_ROLLUP         9
#define SF_ABORT         10
#define SF_TERM          11

static void (*SPL_fns[SPL_STATE_NO])() =
  {
  SPL_SetPsCond,         /* SF_EPSCOND    */
  SPL_GetPPs,            /* SF_GETPPS     */
  SPL_SetCsr,            /* SF_SETCSR     */
  SPL_ToTop,             /* SF_TOTOP      */
  SPL_ToLeftEnd,         /* SF_TOLEFTEND  */
  SPL_GetPs,             /* SF_GETPS      */
  SPL_IsRightEnd,        /* SF_ISRIGHTEND */
  SPL_ToRight,           /* SF_TORIGHT    */
  SPL_IsEnd,             /* SF_ISEND      */
  SPL_RollUp,            /* SF_ROLLUP     */
  SPL_AbortPend,         /* SF_ABORT      */
  SPL_Terminate          /* SF_TERM       */
  };

static BYTE FSM_SPL[SPL_STATE_NO][SPL_EVENT_NO] =
  {
  //  events -->
  // states
  //   |
  //   V                EV_DATA         EV_ACK         EV_NACK     EV_END      EV_ERROR    EV_ABORT    EV_CONT      EV_BRK
  /* SF_EPSCOND    */ { 0xff          , SF_GETPPS    , SF_TERM   , 0xff      , SF_TERM   , 0xff      , 0xff       , 0xff      },
  /* SF_GETPPS     */ { SF_SETCSR     , 0xff         , SF_TERM   , 0xff      , SF_TERM   , 0xff      , 0xff       , 0xff      },
  /* SF_SETCSR     */ { 0xff          , SF_TOTOP     , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_TOTOP      */ { 0xff          , SF_TOLEFTEND , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_TOLEFTEND  */ { 0xff          , SF_GETPS     , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_GETPS      */ { SF_ISRIGHTEND , 0xff         , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_ISRIGHTEND */ { 0xff          , 0xff         , 0xff      , 0xff      , SF_TERM   , SF_ABORT  , SF_TORIGHT , SF_ISEND  },
  /* SF_TORIGHT    */ { 0xff          , SF_GETPS     , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_ISEND      */ { 0xff          , 0xff         , 0xff      , 0xff      , SF_TERM   , SF_ABORT  , SF_ROLLUP  , SF_TERM   },
  /* SF_ROLLUP     */ { 0xff          , SF_TOLEFTEND , SF_TERM   , 0xff      , SF_TERM   , SF_ABORT  , 0xff       , 0xff      },
  /* SF_ABORT      */ { SF_TERM       , SF_TERM      , SF_TERM   , SF_TERM   , SF_TERM   , SF_TERM   , SF_TERM    , SF_TERM   },
  /* SF_TERM       */ { 0xff          , 0xff         , 0xff      , 0xff      , 0xff      , 0xff      , 0xff       , 0xff      }
  };

int       hFile=-1;
OFSTRUCT  of;
int       nStartCol;
int       nEndCol;
int       nMaxCol;
BOOL      bJpnMode;
BOOL      bDbcsText;
char      Footor[7];
int       BufferPtr[16];
char      PsBuffer[16][256];

//******************************************************************************
//
//  StartSpoolToFile - Make an ASCII file from a host spool file
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void StartSpoolToFile( HWND hWnd )               //
{                                                //
  FARPROC lpProcModalDialog;                     //
  BOOL    bContinue;                             //
                                                 //
  lpProcModalDialog = MakeProcInstance(PCFilenameDialog, hGlobalInst);
                                                 //
  bContinue = DialogBox(hGlobalInst, MAKEINTRESOURCE(PCFILENAME), hWnd,     lpProcModalDialog);
                                                 // Get PC file name
  FreeProcInstance(lpProcModalDialog);           //

  if ( bContinue && InitSession () )             // Initiate session conversation
  {                                              //
    aEPSCOND   = GlobalAddAtom(zEPSCOND  );      // Register Items
    aEPS       = GlobalAddAtom(zEPS      );      //
    aPS        = GlobalAddAtom(zPS       );      //
    aSETCURSOR = GlobalAddAtom(zSETCURSOR);      //
    wOperation = SPOOL_TO_FILE;                  //
    State = SF_EPSCOND;                          // Set Initial state
    nStartCol  = 0;                              // Initializes variables
    nEndCol    = 0;                              //
    nMaxCol    = 0;                              //
    SPL_SetPsCond();                             // Start Finite State Machine
  }                                              //
}                                                //

//******************************************************************************
//
//  FSM_SpoolToFile - Finite State Machine for Spool To File
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void FSM_SpoolToFile( BYTE Event, ATOM aItem,  HANDLE hData )
{                                                //
  if (hData)                                     // receive new data?
  {                                              //
    if (hRcvData)                                // old data remains?
    {                                            //
      GlobalFree(hRcvData);                      // free it
    }                                            //
    hRcvData = hData;                            // save the handle
  }                                              //
  if ( ( (Event != EV_DATA) &&                   // check if item is correct
         (Event != EV_ACK)  &&                   //
         (Event != EV_NACK)    ) ||              //
       (SPL_CheckItem(aItem)   )   )             //
  {                                              //
    State = FSM_SPL[State][Event];               // get new state
    (*SPL_fns[State])();                         // process for new state
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_SetPsCond - Process in SF_EPSCOND state
//
//  PURPOSE: Set condition for getting a part of PS (from (1,31) to (1,50)).
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_SetPsCond( void )                       //
{                                                //
  PrepGetPartialPs ( 1, 29, 24 );                // Set PS service condition
}                                                //

//******************************************************************************
//
//  SPL_GetPPs - Process in SF_GETPPS state
//
//  PURPOSE: Get a part of PS (from (1,29) to (1,53)).
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_GetPPs( void )                          //
{                                                //
  RequestGetPartPs();                            // Get partial PS
}                                                //

//******************************************************************************
//
//  SPL_SetCsr - Process in SF_SETCSR state
//
//  PURPOSE: Set the cursor to the command line (3,22)
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_SetCsr( void )                          //
{                                                //
  lpDDE_EPS_CF_DSPTEXT  lpData;                  //
  BOOL                  bFree;                   //
  BOOL                  bAck;                    //
  BOOL                  bValidPs = FALSE;        //
                                                 //
  if (hRcvData)                                  //
  {                                              //
    lpData = (lpDDE_EPS_CF_DSPTEXT) GlobalLock(hRcvData);
    if (HIWORD(lpData) != (int)NULL)             //
    {                                            //
      bFree = lpData->DDEdata.fRelease;          // Save flags
      bAck  = lpData->DDEdata.fAckReq;           //
                                                 //
      if (_fmemicmp(lpData->DDEeps.PSData,       //
                    zTopIDJ,                     //
                    lstrlen(zTopIDJ)) == (int)NULL) // Test for "スプール・ファイルの表示"
      {                                          //
        bValidPs = TRUE;                         // Valid screen
        bJpnMode = TRUE;                         // Screen is in Japanese
      }                                          //
      else if (_fmemicmp(&(lpData->DDEeps.PSData[2]),
                         zTopID,                 //
                         lstrlen(zTopID)) == (int)NULL) // Test for "DISPLAY SPOOLED FILE"
      {                                          //
        bValidPs = TRUE;                         // Valid screen
        bJpnMode = FALSE;                        // Screen is in English
      }                                          //
                                                 //
      GlobalUnlock(hRcvData);                    //
                                                 //
      if (bFree)                                 // Should be freed?
      {                                          //
        GlobalFree(hRcvData);                    // Free it
        hRcvData = NULL;                         //
      }                                          //
      if (bAck)                                  // Must post ack to DDE server?
      {                                          //
        PostMessage (hSessWnd,                   //  Post DDE ACK message
                     WM_DDE_ACK,                 //
                     (WPARAM)hMainWnd,           //
                     PackDDElParam(WM_DDE_ACK, DDE_ACK, aEPS) );  //
      }                                          //
                                                 //
      if (bValidPs)                              // "Display Spool File" screen?
      {                                          // Yes
        LoadString(hGlobalInst,                  // put up modeless abort box
                   LS_ABORT_TITLEF,              //
                   zAbortTitle,                  //
                   sizeof(zAbortTitle));         //
        hAbortDialog = DisplayAbortDialog( hMainWnd );
                                                 //
        SetCursorPosition ( 3, 22 );             // Set the cursor position
      }                                          //
    }                                            //
    else                                         //  GlobalLock Error
    {                                            //
      GlobalFree(hRcvData);                      //
      hRcvData = NULL;                           //
    }                                            //
  }                                              //
  if (!bValidPs)                                 // Not "Display Spool File" screen or
  {                                              //  some error happens
    LoadString(hGlobalInst,                      // put up modeless abort box
               LS_ERROR3_TEXT,                   //
               zMsgBuffer,                       //
               sizeof(zMsgBuffer));              //
    MessageBox(NULL,                             // Display error message
               (LPSTR) zMsgBuffer,               //
               (LPSTR) zSpoolToFileClassPrefix,  //
               MB_OK | MB_ICONQUESTION );        //
    PostMessage (hMainWnd,                       // post messgae for EV_ERROR
                 WM_USER_ERROR,                  //
                 (WPARAM)hMainWnd,               //
                 MAKELONG(NULL, NULL) );         //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_ToTop - Process in SF_TOTOP state
//
//  PURPOSE: Send "*TOP  " and Enter Key.
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_ToTop( void )                           //
{                                                //
  hFile = OpenFile(zPCFilename, &of, OF_CREATE); // Open file
  if (hFile > 0)                                 //
  {                                              //
    ExecuteKeystrokes("\"*TOP  \", backtab, enter");  // Send keystrokes ("*TOP  ", backtab, enter)
  }                                              //
  else                                           //
  {                                              //
    LoadString(hGlobalInst,                      // put up modeless abort box
               LS_ERROR4_TEXT,                   //
               zMsgBuffer,                       //
               sizeof(zMsgBuffer));              //
    MessageBox(NULL,                             // Display error message
               (LPSTR) zMsgBuffer,               //
               (LPSTR) zSpoolToFileClassPrefix,  //
               MB_OK | MB_ICONQUESTION );        //
    PostMessage (hMainWnd,                       // post messgae for EV_ERROR
                 WM_USER_ERROR,                  //
                 (WPARAM)hMainWnd,               //
                 MAKELONG(NULL, NULL) );         //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_ToLeftEnd - Process in SF_TOLEFTEND state
//
//  PURPOSE: Send keystrokes ("W1    ", backtab, enter)
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_ToLeftEnd( void )                       //
{                                                //
  int  i;                                        //
  ExecuteKeystrokes("\"W1    \", backtab, enter");  // Send keystrokes ("W1    ", backtab, enter)
                                                 //
  for (i=0; i<16; i++)                           // Initializes the table
  {                                              // of Buffer pointor
    BufferPtr[i] = 0;                            //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_GetPs - Process in SF_GETPS state
//
//  PURPOSE: Get PS in CF_DSPTEXT format
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_GetPs( void )                           //
{                                                //
  RequestGetPs();                                // Get PS in CF\DSPTEXT format
}                                                //

//******************************************************************************
//
//  SPL_IsRightEnd - Process in SF_ISRIGHTEND state
//
//  PURPOSE: Gather lines of Profs Note and determine if the right end of the
//           note.
//
//  COMMENTS:
//
//******************************************************************************
void SPL_IsRightEnd( void )                      //
{                                                //
  lpDDE_PS_CF_DSPTEXT  lpData;                   //
  BOOL                 bFree;                    //
  BOOL                 bAck;                     //
  BOOL                 bEnd = FALSE;             //
  int                  i,j;                      //
  int                  nPtr;                     //
  int                  offset;                   //
                                                 //
  if (hRcvData)                                  //
  {                                              //
    lpData = (lpDDE_PS_CF_DSPTEXT) GlobalLock(hRcvData);
    if (HIWORD(lpData) != (int)NULL)             //
    {                                            //
      bFree = lpData->DDEdata.fRelease;          // save flags
      bAck  = lpData->DDEdata.fAckReq;           //
                                                 //
      GetStartEndCol( (LPSTR)&(lpData->DDEps.PSData[OffsetInPs(3, 67)]),
                      (LPINT)&nStartCol,         // Retrieve the start and end
                      (LPINT)&nEndCol );         //  column numbers
      if (nMaxCol > 0)                           // Already max Column number
      {                                          //  has been deterimend?
        if (nEndCol == nMaxCol)                  // compare with it
        {                                        //
          bEnd = TRUE;                           // Reached the right edge
        }                                        //
      }                                          //
      else                                       // The very first line
      {                                          //
        if ((nEndCol - nStartCol) < 74 )         // text truncated in the middle
        {                                        //  of screen?
          nMaxCol = nEndCol;                     // found the max column number
          bEnd = TRUE;                           //
        }                                        //
        else                                     //
        {                                        //
          if ((nEndCol - nStartCol) == 74)       // 74 columns per row displayed?
          {                                      //
            bDbcsText = TRUE;                    // Japanes file
          }                                      //
          else                                   //
          {                                      //
            bDbcsText = FALSE;                   // English file
          }                                      //
        }                                        //
      }                                          //
                                                 //
      for (i=6; i<22; i++)                       // Gathers text lines
      {                                          //
        if (bDbcsText)                           // Japanese Text?
        {                                        //
          offset = OffsetInPs(i, 2);             //
          nPtr = BufferPtr[i-6];                 //
          if ( (lpData->DDEps.PSData[offset] == ' ' ) ||
               (lpData->DDEps.PSData[offset] == 0x0e)    )
          {                                      // Check if this line starts
            j=0;                                 //  from DBCS 2nd byte
            if (nPtr > 0)                        //
            {                                    //
              nPtr--;                            //
            }                                    //
          }                                      //
          else                                   //
          {                                      //
            j=1;                                 //
          }                                      //
          for (; j <= (nEndCol-nStartCol); j++)  // retrieve each line of  data
          {                                      //
            if (IsSoSi(lpData->DDEps.PSData[offset+j+1]))
            {                                    // SO/SI character?
              if (j == (nEndCol - nStartCol))    // Last position?
              {                                  //
                nPtr++;                          // adjust write pointor
              }                                  //  for future use
              else                               //
              {                                  //
                if (!bRemoveSoSi)                // SO/SI remove?
                {                                //
                  PsBuffer[i-6][nPtr] = lpData->DDEps.PSData[offset+j+1];
                  nPtr++;                        //
                }                                //
              }                                  //
            }                                    //
            else                                 // not SO/SI character
            {                                    //
              if (IsDbcsHiByte(lpData->DDEps.PSData[offset+j+1]))
              {                                  // DBCS 1st byte?
                PsBuffer[i-6][nPtr] = lpData->DDEps.PSData[offset+j+1];
                nPtr++;                          //
                j++;                             //
                PsBuffer[i-6][nPtr] = lpData->DDEps.PSData[offset+j+1];
                nPtr++;                          //
              }                                  //
              else                               // SBCS character
              {                                  //
                PsBuffer[i-6][nPtr] = lpData->DDEps.PSData[offset+j+1];
                nPtr++;                          //
              }                                  //
            }                                    //
          }                                      //
          BufferPtr[i-6] = nPtr;                 // save write pointer
        }                                        //
        else                                     // English Text
        {                                        //
          offset = OffsetInPs(i, 2);             //
          nPtr = BufferPtr[i-6];                 //
          if (nPtr > 0)                          //
          {                                      //
            nPtr--;                              //
          }                                      //
          for (j=0; j <= (nEndCol-nStartCol); j++) // copy one line data
          {                                      //
            PsBuffer[i-6][nPtr] = lpData->DDEps.PSData[offset+j];
            nPtr++;                              //
          }                                      //
          BufferPtr[i-6] = nPtr;                 // save write pointer
        }                                        //
      }                                          //
                                                 //
      if (bEnd)                                  // reached the right edge?
      {                                          //
         offset = OffsetInPs(22, 74);            //
         for (i = 0; i < 6; i++)                 // Save "More..." or "BOTTOM"
         {                                       //
            Footor[i] = lpData->DDEps.PSData[offset+i];  //
         }                                       //
         Footor[6] = 0;                          //
         for (i=0; i < 16; i++)                  // Write data to disk
         {                                       //
           nPtr = BufferPtr[i];                  //
           PsBuffer[i][nPtr] = 0x0d;             //
           nPtr++;                               //
           PsBuffer[i][nPtr] = 0x0a;             //
           nPtr++;                               //
           _lwrite (hFile, PsBuffer[i], (WORD)nPtr );
         }                                       //
      }                                          //
                                                 //
      GlobalUnlock(hRcvData);                    //
                                                 //
      if (bFree)                                 // Should be freed?
      {                                          //
        GlobalFree(hRcvData);                    //
        hRcvData = NULL;                         //
      }                                          //
      if (bAck)                                  // Must post ack to DDE server?
      {                                          //
        PostMessage (hSessWnd,                   //
                     WM_DDE_ACK,                 //
                     (WPARAM)hMainWnd,           //
                     PackDDElParam(WM_DDE_ACK, DDE_ACK, aPS) );   //
      }                                          //
                                                 //
      if (bEnd)                                  // Reached the right edge ?
      {                                          //
        PostMessage (hMainWnd,                   // post messgae for EV_BRK
                     WM_USER_BREAK,              //
                     (WPARAM)hMainWnd,           //
                     MAKELONG(NULL, NULL) );     //
      }                                          //
      else                                       //
      {                                          //
        PostMessage (hMainWnd,                   // post messgae for EV_CONT
                     WM_USER_CONT,               //
                     (WPARAM)hMainWnd,           //
                     MAKELONG(NULL, NULL) );     //
      }                                          //
    }                                            //
    else                                         //
    {                                            //
      GlobalFree(hRcvData);                      //
      hRcvData = NULL;                           //
    }                                            //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_ToRignt - Process in SF_TORIGHT state
//
//  PURPOSE: Send "Wnnn  " and Enter Key.
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_ToRight( void )                         //
{                                                //
  char   Temp[50];                               //
                                                 //
  lstrcpy (Temp, "\"W     \", backtab, enter");  //
                                                 //
  if (nEndCol >= 100)                            //
  {                                              //
    Temp[2] = (char)('0' + nEndCol/100);         //
    Temp[3] = (char)('0' + (nEndCol%100)/10);    //
    Temp[4] = (char)('0' + (nEndCol%10));        //
  }                                              //
  else                                           //
  {                                              //
    Temp[2] = (char)('0' + (nEndCol%100)/10);    //
    Temp[3] = (char)('0' + (nEndCol%10));        //
  }                                              //
  ExecuteKeystrokes( (LPSTR)Temp );              // Send keystrokes ("Wnnn  ", backtab, enter)
}                                                //

//******************************************************************************
//
//  SPL_IsEnd - Process in SF_ISEND state
//
//  PURPOSE: Gather lines of Profs Note and determine if the end of the note
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_IsEnd( void )                           //
{                                                //
  BOOL   bCont = TRUE;                           //
                                                 //
  if (bJpnMode)                                  // Is screen in Japanese?
  {                                              //
    Footor[4] = 0x00;                            // Compare with "終り"
    if ( !lstrcmpi( (LPSTR)Footor, (LPSTR)zBottomIDJ ) )
    {                                            //
      bCont = FALSE;                             //
    }                                            //
  }                                              //
  else                                           // In English
  {                                              //
    if ( !lstrcmpi( (LPSTR)Footor, (LPSTR)zBottomID ) )
    {                                            // Compare with "BOTTOM"
      bCont = FALSE;                             //
    }                                            //
  }                                              //
                                                 //
  if (bCont)                                     //
  {                                              //
    PostMessage (hMainWnd,                       // post messgae for EV_CONT
                 WM_USER_CONT,                   //
                 (WPARAM)hMainWnd,               //
                 MAKELONG(NULL, NULL) );         //
  }                                              //
  else                                           //
  {                                              //
    PostMessage (hMainWnd,                       // post messgae for EV_BRK
                 WM_USER_BREAK,                  //
                 (WPARAM)hMainWnd,               //
                 MAKELONG(NULL, NULL) );         //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_RollUp - Process in SF_ROLLUP state
//
//  PURPOSE: Send "Roll Up" keystroke.
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_RollUp( void )                          //
{                                                //
  ExecuteKeystrokes("roll up");                  // Send keystroke (RollUp key)
}                                                //

//******************************************************************************
//
//  SPL_AbortPend - Process in SF_ABORT state
//
//  PURPOSE: Wait for WM_DDE_DATA or WM_DDE_ACK, and then abort printing.
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_AbortPend( void )                       //
{                                                //
  if (hAbortDialog)                              // Abort DialogBox displayed?
  {                                              //
    DestroyAbortDialog(hAbortDialog, hMainWnd);  // Destroy it
    hAbortDialog = NULL;                         //
  }                                              //
}                                                //

//******************************************************************************
//
//  SPL_Terminate - Process in SF_TERM state
//
//  PURPOSE: Terminate session conversation.
//
//
//  COMMENTS:
//
//******************************************************************************
void SPL_Terminate( void )                       //
{                                                //
  if (hFile > 0)                                 //
  {                                              //
    _lclose(hFile);                              //
    hFile = -1;                                  //
  }                                              //
  if (hRcvData)                                  // data remains?
  {                                              //
    GlobalFree(hRcvData);                        // Free it
    hRcvData = NULL;                             //
  }                                              //
  if (hAbortDialog)                              // Abort DialogBox displayed?
  {                                              //
    DestroyAbortDialog(hAbortDialog, hMainWnd);  // Destroy it
    hAbortDialog = NULL;                         //
  }                                              //
  GlobalDeleteAtom(aSETCURSOR);                  // Unregister items
  GlobalDeleteAtom(aPS       );                  //
  GlobalDeleteAtom(aEPS      );                  //
  GlobalDeleteAtom(aEPSCOND  );                  //
  TerminateSession();                            // terminate session conversation
  wOperation = (unsigned short)NULL;             //
}                                                //

//******************************************************************************
//
//  SPL_CheckItem - Check the item is proper to the current state
//
//  PURPOSE: Determine if the ATOM value is correct or not.
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL SPL_CheckItem( ATOM aItem )                 //
{                                                //
  BOOL   bRC = FALSE;                            //
                                                 //
  switch (State)                                 //
  {                                              //
    case SF_EPSCOND:                             //
      if (aItem == aEPSCOND)                     //
      {                                          //
        bRC = TRUE;                              //
      }                                          //
      break;                                     //
                                                 //
    case SF_GETPPS:                              //
      if (aItem == aEPS)                         //
      {                                          //
        bRC = TRUE;                              //
      }                                          //
      break;                                     //
                                                 //
    case SF_GETPS:                               //
      if (aItem == aPS)                          //
      {                                          //
        bRC = TRUE;                              //
      }                                          //
      break;                                     //
                                                 //
    case SF_SETCSR:                              //
      if (aItem == aSETCURSOR)                   //
      {                                          //
        bRC = TRUE;                              //
      }                                          //
      break;                                     //
                                                 //
    case SF_TOTOP:                               //
    case SF_TOLEFTEND:                           //
    case SF_ISRIGHTEND:                          //
    case SF_TORIGHT:                             //
    case SF_ISEND:                               //
    case SF_ROLLUP:                              //
    case SF_ABORT:                               //
    case SF_TERM:                                //
      bRC = TRUE;                                //
      break;                                     //
                                                 //
    default:                                     //
      break;                                     //
  }                                              //
  return (bRC);                                  //
}                                                //
