//******************************************************************************
//
//  File name   : SPDDE.C
//
//  Description : 5250 Session DDE interface functions for Spl2File DDE application
//
//  FUNCTIONS:
//
//
//  COMMENTS:
//
//  Copyright  (C) 1993, 1996 IBM Corporation
//                        All rights reserved.
//
//******************************************************************************

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

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

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

static uchar  zMenuServ[17];
static uchar  zMenuBar[17];
static uchar  zMenuMap[17];
static uchar  zABOUT[17];
static uchar  zSPOOL[17];
static uchar  zZCONFG[17];

static uchar *zMenuStruct =
{
"POPUP \"Sp&l2File\"\r\n\
BEGIN\r\n\
  MENUITEM \"Convert a &spool file\", SPOOL\r\n\
  MENUITEM SEPARATOR\r\n\
  MENUITEM \"&Config...\", ZCONFG\r\n\
  MENUITEM SEPARATOR\r\n\
  MENUITEM \"&About Spl2File...\", ABOUT\r\n\
END\r\n"
};

//******************************************************************************
//
//  InitDDE - Initialize various items needed for DDE
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL InitDDE( void )
{
  LoadString(hGlobalInst,  LS_16STR_FORMAT, zFmtBuffer, sizeof(zFmtBuffer));
  LoadString(hGlobalInst,  LS_DDE_TOKENS,   zMsgBuffer, sizeof(zMsgBuffer));

  sscanf( zMsgBuffer,                          // Input String
          zFmtBuffer,                          // sscanf format to use
          zMenuServ,                           // MenuServ
          zMenuBar,                            // MenuBar
          zMenuMap,                            // MenuMap
          zSPOOL,                              // SPOOL TO FILE
          zZCONFG,                             // CONFIGURE MYPRINT
          zABOUT   );                          // ABOUT
                                               //
  lstrcat(zMenuServ, zSessionID );             // Append Session ID

  return( TRUE );                              //
}                                              //

//******************************************************************************
//
//  SpDDEInitiate - Process the DDE_INITIATE message
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL FAR SpDDEInitiate(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{                                                   //
                                                    //
  ATOM aApplication  = LOWORD( lParam );            //
  ATOM aTopic        = HIWORD( lParam );            //
                                                    //
  ATOM aMenuServ     = GlobalAddAtom( (LPSTR)zMenuServ );  // Register Atoms
  ATOM aMenuBar      = GlobalAddAtom( (LPSTR)zMenuBar  );  //
  ATOM aSPOOL        = GlobalAddAtom( (LPSTR)zSPOOL    );  //
  ATOM aZCONFG       = GlobalAddAtom( (LPSTR)zZCONFG   );  //
  ATOM aABOUT        = GlobalAddAtom( (LPSTR)zABOUT    );  //

  BOOL bRC           = FALSE;                       //

  if( aApplication == aMenuServ )                   //
  {                                                 //
    if( aTopic == aMenuBar )                        // Setup a menu bar?
    {                                               // Yes,
      {                                             //
        hDDEClientWnd  = (HWND)wParam;              // Save away client window handle
        bRC            = TRUE;                      // Signal success
        if( !SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hWnd, MAKELONG( aApplication, aTopic )) )
        {                                           //
          GlobalDeleteAtom( aApplication );         // Error, delete client's ATOMS
          GlobalDeleteAtom( aTopic    );            // Error, delete client's ATOMS
        }                                           //
      }                                             //
    }                                               //
    else if( aTopic == aSPOOL || aTopic == aZCONFG  //
             || aTopic == aABOUT )                  //
    {                                               //
      HWND         hSessionWnd;                     //
      WORD         uCMD;                            //
      bRC        = TRUE;                            // Signal success
      hDDEClientWnd  = (HWND)wParam;                // Save away client window handle
      if( !SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)hWnd, MAKELONG( aApplication, aTopic )) )
      {                                             //
        GlobalDeleteAtom( aApplication );           // Error, delete client's ATOMS
        GlobalDeleteAtom( aTopic    );              // Error, delete client's ATOMS
      }                                             //
      if( aTopic == aSPOOL )                        // convert spool to file
      {                                             //
        uCMD = ID_SPOOL;                            //
      }                                             //
      else if( aTopic == aZCONFG )                  // config
      {                                             //
        uCMD = ID_ZCONFG;                           //
      }                                             //
      else if( aTopic == aABOUT )                   // about
      {                                             //
        uCMD = ID_ABOUT;                            //
      }                                             //
      hSessionWnd = FindWindow((LPSTR) zSessionClassName, (LPSTR) NULL);
      PostMessage(hWnd, WM_COMMAND, uCMD, MAKELONG( wParam, hSessionWnd) );
    }                                               //
  }                                                 //

  GlobalDeleteAtom( aMenuServ );                    // Delete Atoms
  GlobalDeleteAtom( aMenuBar  );                    //
  GlobalDeleteAtom( aSPOOL    );                    //
  GlobalDeleteAtom( aZCONFG   );                    //
  GlobalDeleteAtom( aABOUT    );                    //

  return( bRC );                                    //
}                                                   //

//******************************************************************************
//
//  SpDDEAck - Process the DDE_ACK message
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL FAR SpDDEAck(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{                                                   //
  BYTE Event;                                       //
  BOOL bRC           = FALSE;                       // Error until proven otheriwse ...
  UINT uiLo, uiHi;                                  //

  if ((LOWORD(lParam) == aIBM5250) &&               // Check Application and
      (HIWORD(lParam) == aSession))                 //  topic name
  {                                                 //
    hSessWnd = (HWND)wParam;                        // Ack of WM_DDE_INITIATE
    bRC = TRUE;                                     //
  }                                                 //
  else if ((HWND)wParam == hSessWnd)                // Ack of other messages
  {                                                 //
    UnpackDDElParam(WM_DDE_ACK, lParam, (PUINT)&uiLo, (PUINT)&uiHi);

    if (uiLo == DDE_ACK)                            // O.K.
    {                                               //
      Event = EV_ACK;                               //
    }                                               //
    else                                            // N.G.
    {                                               //
      Event = EV_NACK;                              //
    }                                               //

    if (uLastMessage == WM_DDE_EXECUTE)             // process next step
    {                                               //
      bRC = FSM_Event( Event, (unsigned short)NULL, (HANDLE)uiHi ); //
    }                                               //
    else                                            //
    {                                               //
      bRC = FSM_Event( Event, (ATOM)uiHi, NULL );   //
    }                                               //
  }                                                 //
  return( bRC  );                                   //
}                                                   //

//******************************************************************************
//
//  SpDDEData - Process the DDE_DATA message
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL FAR SpDDEData(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{                                                   //
  BOOL bRC           = FALSE;                       // Error until proven otheriwse ...
  UINT uiLo, uiHi;                                  //

  UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT)&uiLo, (PUINT)&uiHi);
  if ((HWND)wParam == hSessWnd)                     //
  {                                                 //
    bRC = FSM_Event( EV_DATA, (ATOM)uiHi, (HANDLE)uiLo );
  }                                                 // process the next step
  return( bRC  );                                   //
}                                                   //

//******************************************************************************
//
//  SpDDERequest - Process the DDE_REQUEST message
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL FAR SpDDERequest(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
  ATOM aMenuMap = GlobalAddAtom( zMenuMap );     // Holder Atom
  ATOM aItem    = HIWORD( lParam );              // Requested aItem
  WORD cfFormat = LOWORD( lParam );              // Requested Format
  BOOL bRC      = FALSE;                         // Error until proven otheriwse ...
  DDEDATA FAR *   lpData;                        // Long Pointer to DATA structure
  HANDLE          hData;                         // Handle       to DATA structure
  DWORD           dwSize = (sizeof(DDEDATA) + strlen(zMenuStruct) + 16);

  if( (aItem == aMenuMap) && (cfFormat == CF_TEXT) )
  {                                              //
    if( (hData = GlobalAlloc(DDE_GLOBAL, dwSize)) != NULL )
    {                                            //
      if( (lpData = (DDEDATA FAR *) GlobalLock(hData)) != NULL ) //
      {                                          //
        lpData->cfFormat = cfFormat;             // Format
        lpData->fAckReq  = FALSE;                // No return ACK
        lpData->fRelease = TRUE;                 // Client GlobalFree this buffer
        lstrcpy(lpData->Value, zMenuStruct);     // Data
        GlobalUnlock(hData);                     // Unlock the buffer
        aItem = GlobalAddAtom( zMenuMap );       // Add item for call
        if( !PostMessage((HWND)wParam, WM_DDE_DATA, (WPARAM)hWnd,
                         PackDDElParam(WM_DDE_DATA, (UINT)hData, aItem)) )
        {                                        //
          GlobalDeleteAtom( aItem  );            // Delete the item
          GlobalFree(hData);                     // and free the data
          TerminateConversation();               //
        }                                        //
        else                                     //
        {                                        //
          bRC = TRUE;                            // Success!
        }                                        //
      }                                          //
      else                                       // Couldn't lock it ...
      {                                          //
        GlobalFree(hData);                       // So free it .....
      }                                          //
    }                                            //
  }                                              //
  GlobalDeleteAtom( aMenuMap );                  // Delete the holder atom
  return( bRC  );                                // return bRC
}                                                //

//******************************************************************************
//
//  SpDDETerminate - Process the DDE_TERMINATE message
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
BOOL FAR SpDDETerminate(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{                                                //
  if ((HWND)wParam == hSessWnd)                  //
  {                                              //
    hSessWnd = NULL;                             //
  }                                              //
  else                                           //
  {                                              //
    if( hDDEClientWnd != NULL )                  // Is client alive?
    {                                            // Terminate him
      TerminateConversation();                   //
    }                                            //
  }                                              //

  return( TRUE );                                // return success
}                                                //

//******************************************************************************
//
//  PrepGetPartialPs - Issues "Set Prsentation Space Service Condition".
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void PrepGetPartialPs(int nRow, int nCol, int nLength)
{                                                //
  HANDLE            hData;                       //
  lpDDE_PSSERVCOND  lpPsCond;                    //

  hData = GlobalAlloc(WC_DDE_GLOBAL, (DWORD)(sizeof(DDE_PSSERVCOND)));
  if (hData)                                     // allocate message buffer
  {                                              //
    lpPsCond = (lpDDE_PSSERVCOND)GlobalLock(hData);
    if (HIWORD(lpPsCond) != (int)NULL)           //
    {                                            //
      lpPsCond->DDEpoke.fRelease            = TRUE;                    //
      lpPsCond->DDEpoke.cfFormat            = CF_DSPTEXT;              // format
      lpPsCond->DDEcond.uPSStart            = (nRow-1) * 80 + (nCol-1);// PS position
      lpPsCond->DDEcond.uPSLength           = nLength;                 // Length
      lpPsCond->DDEcond.szTargetString[0] = (char)NULL;                //
      GlobalUnlock(hData);                       //
      if (hSessWnd)                              //
      {                                          //
        PostMessage(hSessWnd,                    // Post message to DDE server
                    WM_DDE_POKE,                 //  (PC/5250)
                    (WPARAM)hMainWnd,            //
                    PackDDElParam(WM_DDE_POKE, (UINT)hData, aEPSCOND));
        uLastMessage = WM_DDE_POKE;              //
      }                                          //
      else                                       //
      {                                          //
        GlobalFree(hData);                       //
      }                                          //
    }                                            //
    else                                         //
    {                                            //
      GlobalFree(hData);                         //
    }                                            //
  }                                              //
}                                                //

//******************************************************************************
//
//  RequestGetPs - Issues "Get Prsentation Space" (CF_DSPTEXT).
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void  RequestGetPs( void )                       //
{                                                //
  if (hSessWnd)                                  //
  {                                              //
    PostMessage(hSessWnd,                        //
                WM_DDE_REQUEST,                  //
                (WPARAM)hMainWnd,                //
                MAKELONG(CF_DSPTEXT, aPS));      //
    uLastMessage = WM_DDE_REQUEST;               //
  }                                              //
}                                                //

//******************************************************************************
//
//  RequestGetPartPs - Issues "Get Partial Prsentation Space" (CF_TEXT).
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void  RequestGetPartPs( void )                   //
{                                                //
  if (hSessWnd)                                  //
  {                                              //
    PostMessage(hSessWnd,                        //
                WM_DDE_REQUEST,                  //
                (WPARAM)hMainWnd,                //
                MAKELONG(CF_DSPTEXT, aEPS));     //
    uLastMessage = WM_DDE_REQUEST;               //
  }                                              //
}                                                //

//******************************************************************************
//
//  ExecuteKeystrokes - Issues "Session Execute Macro" SENDKEY command
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void  ExecuteKeystrokes( LPSTR lpKeys )          //
{                                                //
  HANDLE   hData;                                //
  LPSTR    lpData;                               //
  BOOL     bRequest = FALSE;                     //

  hData = GlobalAlloc(WC_DDE_GLOBAL, (DWORD)256 );  //
  if (hData)                                     //
  {                                              //
    lpData = GlobalLock(hData);                  //
    if (HIWORD(lpData) != (int)NULL)             //
    {                                            //
      lstrcpy(lpData, "[SENDKEY(");              // command name
      lstrcat(lpData, "wait inp inh");           // wait while input inhibit
      lstrcat(lpData, ",");                      //
      lstrcat(lpData, lpKeys);                   //
      lstrcat(lpData, ",");                      //
      lstrcat(lpData, "wait inp inh");           // wait while input inhibit
      lstrcat(lpData, ")]");                     //
      GlobalUnlock(hData);                       //

      if (hSessWnd)                              //
      {                                          //
        PostMessage(hSessWnd,                    // post to PC/5250
                    WM_DDE_EXECUTE,              //
                    (WPARAM)hMainWnd,            //
                    (LPARAM)hData);              //
        uLastMessage = WM_DDE_EXECUTE;           //
        bRequest = TRUE;                         //
      }                                          //
    }                                            //
    else                                         //
    {                                            //
      GlobalFree(hData);                         //
    }                                            //
  }                                              //
  if (!bRequest)                                 //
  {                                              //
    PostMessage(hMainWnd,                        //
                WM_USER_ERROR,                   //
                (WPARAM)hMainWnd,                //
                MAKELONG(NULL, NULL) );          //
  }                                              //
}                                                //

//******************************************************************************
//
//  SetCursorPosition - Issues "Set Cursor Position".
//
//  PURPOSE:
//
//
//  COMMENTS:
//
//******************************************************************************
void SetCursorPosition(int nRow, int nCol)
{                                                //
  HANDLE            hData;                       //
  lpDDE_SETCURSOR   lpCursor;                    //

  hData = GlobalAlloc(WC_DDE_GLOBAL, (DWORD)(sizeof(DDE_SETCURSOR)));
  if (hData)                                     //
  {                                              //
    lpCursor = (lpDDE_SETCURSOR)GlobalLock(hData);
    if (HIWORD(lpCursor) != (int)NULL)           //
    {                                            //
      lpCursor->DDEpoke.fRelease              = TRUE;       //
      lpCursor->DDEpoke.cfFormat              = CF_DSPTEXT; //
      lpCursor->DDEsetcursor.uSetCursorType   = 1;          // Row/Col option
      lpCursor->DDEsetcursor.uSetCursor1 = nRow-1;          // Row number
      lpCursor->DDEsetcursor.uSetCursor2 = nCol-1;          // Column number
      GlobalUnlock(hData);                       //
      if (hSessWnd)                              //
      {                                          //
        PostMessage(hSessWnd,                    //
                    WM_DDE_POKE,                 //
                    (WPARAM)hMainWnd,            //
                    PackDDElParam(WM_DDE_POKE, (UINT)hData, aSETCURSOR));//
        uLastMessage = WM_DDE_POKE;              //
      }                                          //
      else                                       //
      {                                          //
        GlobalFree(hData);                       //
      }                                          //
    }                                            //
    else                                         //
    {                                            //
      GlobalFree(hData);                         //
    }                                            //
  }                                              //
}                                                //
