/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft Corporation, 1989                                 */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME =   Flchkdlg.c
 *
 * DESCRIPTIVE NAME =   Check postscript files and raise dialog boxes
 *
 *
 * VERSION = V2.0
 *
 * DATE       : 3/16/89
 *
 * DESCRIPTION: This Module contains support routines for raising
 *              dialog boxes when the driver tries to write to a file that
 *              already exists.
 *              Checks that file to which PostScript output is going does not
 *              already exist.
 *              If it does, a dialog box will prompt the user to
 *                      - enter a new file name
 *                      - overwrite existing file
 *                      - cancel operation (printing)
 *              If the user enters a new filename, a syntactic check of the
 *              filename is performed before seeing if the newly specified
 *              file exists.  If the newly specified filename is invalid for
 *              any reason, a dialog box will prompt the user to
 *                      - enter a new filename
 *                      - cancel operation (printing)
 *
 *
 * FUNCTIONS    IsFilePipe
 *              R3_File CheckDialogs
 *              CheckForOverwrite
 *              UserFileInvalid
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 *
 *
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define  INCL_WIN
#define  INCL_PM
#include <os2.h>
#include <bseerr.h>

#if      VER20
   #define  INCL_GPIBITMAPS
   #include <pmbitmap.h>
#endif
#define  INCL_DDIBUNDLES
#define  INCL_GREALL
/*            */
#define  PASCAL
#define  FAR
#define  INCL_VMANDDI
#define  INCL_GREALL
#define  INCL_GRE_DEVICESURFACE
#include <ddi.h>
#include <pmddi.h>               /* include commonly used header file */

#include "inc\prdbcone.h"
#include "inc\prddcone.h"
#include "inc\prdtypet.h"
#include "inc\prddtypt.h"
#include "inc\prdstypt.h"
#include "inc\prdptypt.h"
#include "inc\prddct.h"
#include "inc\config.h"
#include "inc\dlgproc.h"
#include "inc\utl.h"
#include "inc\pspagtun.h"             /* V2.174057  Page Tuning */

ULONG EXPENTRY CheckForOverwrite(HWND,SHORT,MPARAM,MPARAM);
ULONG EXPENTRY UserFileInvalid(HWND,SHORT,MPARAM,MPARAM);
BOOL IsFilePipe(PCHAR);
extern HMODULE pscript_module;

/***************************************************************************
 *
 * FUNCTION NAME = IsFilePipe
 *
 *
 * DESCRIPTION   = Check for file pipe
 *
 *
 *
 * INPUT         = pch - ponter to character string
 *
 *
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = TRUE
 *
 *
 *
 * RETURN-ERROR  = FALSE
 *
 *
 *
 ****************************************************************************/

BOOL IsFilePipe( PCHAR pch )
{
  static CHAR szPipe[] = "\\PIPE\\";
  SHORT  ich = 0;

  if (pch[0] == '\\' && pch[1] == '\\')
  {
    /*
    ** Look for server name.
    */
    ich = 2;

    while ((pch[ich] != '\0') && (pch[ich] != '\\'))
    {
      ich++;
    }

    /*
    ** No slash found.
    */
    if (pch[ich] == '\0')
    {
      return( FALSE );
    }
  }


  for ( ; ich < sizeof (szPipe) - 1; ich++)
  {

    if ((pch[ich] != szPipe[ich]) && (pch[ich] != (szPipe[ich]+'a' - 'A')))
    {
      return (FALSE);
    }
  }
  return( TRUE );
}

/***************************************************************************
 *
 * FUNCTION NAME = R3_File CheckDialogs
 *
 * DESCRIPTION   = This function will perform one of three actions. The
 *                 actions depend on various parameters.  If the file to
 *                 which the PostScript output is destined, already exists,
 *                 a dialog box asking the user if he whishes to overwrite
 *                 the file is displayed.  If the filename is valid and
 *                 it does not exist control is returned to the OpenChannel
 *                 function where outputting to the file will continue
 *                 normally.  If the user specifies an invalid file for output,
 *                 a dialog box asking the user to enter another filename is
 *                 displayed.
 *
 * INPUT         = NONE
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = NONE
 *
 * RETURN-ERROR  = NONE
 *
 ****************************************************************************/

void R3_FileCheckDialogs( PDDC pddc )
{
  ULONG       usResult;
  HWND        hWnd, hWndTop;
  HENUM       henum;
  HMODULE     hmod;
  BOOL        fNameIsValid;
  FILESTATUS3 fls3;

  HAB     hAB = (HAB)NULL;
  HMQ     hMQ ;
  MQINFO  mQinfo ;

  /*
  ** Get Window information
  */
  hWndTop = HWND_DESKTOP;
  henum = WinBeginEnumWindows( HWND_DESKTOP );

  if (hWnd = WinGetNextWindow( henum ))
  {
    hWndTop = hWnd;
  }

  WinEndEnumWindows( henum );
  hmod = pscript_module;

  /*           
  ** Make sure there is a message queue
  */
  if ( WinQueryQueueInfo( HMQ_CURRENT, &mQinfo, sizeof(MQINFO) ) == FALSE )
  {
    if ( hAB = WinInitialize( 0 ) )
    {
       hMQ = WinCreateMsgQueue( hAB, 0) ;
       WinCancelShutdown( hMQ, TRUE );
    }
  }

  /*
  ** Loop will execute until decision as to which file to write to
  ** has been made.
  **
  ** Changed loop to break when condition to leave was found @PEN
  ** THIS ALLOWS RESTORE OF SI
  ** ALL "BREAK ;"  WERE "RETURN ;"
  */
  while (TRUE)               /* do until return;                            */
  {
    /*
    ** if filename is syntactically correct use DosQFileMode to
    ** see if it exists or is invalid (for a number of reasons)
    */
    if (fNameIsValid = ValidFilename((PSZ) pddc->pdv->szDestnFile))
    {
      usResult = DosQueryPathInfo( (PSZ) pddc->pdv->szDestnFile, FIL_STANDARD,
                                   &fls3, sizeof(FILESTATUS3) );
    }

    /*
    ** File Exists
    */
    if (fNameIsValid && (usResult == 0) &&
       ((fls3.attrFile == FILE_NORMAL) || (fls3.attrFile == FILE_ARCHIVED)))
    {
      WinAlarm( HWND_DESKTOP, WA_WARNING );

      /*
      ** Open Overwrite check Dialog Box
      */
      usResult = WinDlgBox( HWND_DESKTOP, hWndTop, (PFNWP) CheckForOverwrite,
         (HMODULE) hmod, DLG_OVRWARN, (PVOID) pddc );

      if (usResult == OVERWRITE)
      {
        break;
      }
      else if (usResult == MBID_CANCEL)
      {
        pddc->fCancelOp = TRUE;
        break;
      }

      /*
      ** if (usResult == MBID_OK) do nothing, loop will check
      ** file again
      */
    }
    /*
    **  File does NOT EXIST
    */
    else if (fNameIsValid && (usResult == ERROR_FILE_NOT_FOUND))
    {
      break;
    }
    /*
    ** File is a pipe.
    */
    else if (fNameIsValid && IsFilePipe(pddc->pdv->szDestnFile) && (usResult ==
             ERROR_PATH_NOT_FOUND))
    {
      break;
    }
    else
    {
      /*
      ** any other possibility means file is invalid, so ask user
      ** to enter a new one, by opening Invalid file dialog box
      */
      WinAlarm( HWND_DESKTOP, WA_ERROR );
      usResult = WinDlgBox( HWND_DESKTOP, hWndTop, (PFNWP) UserFileInvalid,
         (HMODULE) hmod, DLG_INVFILE, (PVOID) pddc );

      if (usResult == MBID_CANCEL)
      {
        pddc->fCancelOp = TRUE;
        break;
      }

      /*
      ** if (usResult == MBID_OK) do nothing, loop will check
      ** file again
      */
    }
  }

  /*           
  ** If we needed to create a msg queue then remove it
  */
  if ( hAB )
  {
    WinDestroyMsgQueue (hMQ) ;
    WinTerminate (hAB) ;
  }

  return;
}

/***************************************************************************
 *
 * FUNCTION NAME = CheckForOverwrite
 *
 *
 * DESCRIPTION   = To respond to commands received from user input. User
 *                 can click "OK" or "Cancel", and change file name entry
 *                 field. If filename is not changed when user clicks "OK",
 *                 the dialog will return the OVERWRITE message to the calling
 *                 function.
 *
 *
 *
 * INPUT         = hWnd
 *                 uMsg
 *                 mp1
 *                 mp2
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = 0L
 *
 *
 *
 * RETURN-ERROR  = NONE
 *
 *
 *
 ****************************************************************************/

ULONG EXPENTRY CheckForOverwrite( HWND hWnd, SHORT uMsg, MPARAM mp1, MPARAM mp2 )
{
  PDDC  pddc;
  RECTL rclScreen,rclDialog;
  SHORT sWidth, sHeight, sBLCx, sBLCy;
  CHAR  sz[MAX_FNAMESIZE];
  PSZ   psz;
  SHORT i;

  switch (uMsg)
  {
  case WM_COMMAND:
       pddc = (PDDC) WinQueryWindowULong( hWnd, QWL_USER );

       switch (LOUSHORT( mp1 ))
       {
       case MBID_OK:
            psz = (PSZ)sz;

            /*
            ** store filename string in sz[]
            */
            szNewCopy( psz, (PSZ) pddc->pdv->szDestnFile, sizeof( sz ) );

            /*
            ** get filename string from edit field
            */
            WinQueryDlgItemText( hWnd, EDIT_FILE_OVR, sizeof( pddc->pdv->szDestnFile ),
                                 (PSZ)pddc->pdv->szDestnFile);

            /*
            ** if both strings equal user must want to overwrite
            ** existing file.
            */
            if (sznIsEqual( psz, (PSZ) pddc->pdv->szDestnFile ) )
            {
              WinDismissDlg( hWnd, OVERWRITE );
            }
            else
            {
              WinDismissDlg( hWnd, MBID_OK );
            }
            break;

       case MBID_CANCEL:
            WinDismissDlg( hWnd, MBID_CANCEL );
            break;

       default:
            break;
       }
       break;

  case WM_INITDLG:
       pddc = (PDDC) mp2;

       /*
       ** store this data address so that it can be retrieved elsewhere
       */
       if (!WinSetWindowULong( hWnd, QWL_USER, (ULONG) (PDDC) pddc))
       {
         break;
       }

       /*
       ** MFR : increase file name length to maximum
       */
       WinSendMsg( WinWindowFromID( hWnd, EDIT_FILE_OVR ), EM_SETTEXTLIMIT,
                   MPFROM2SHORT( MAX_FNAMESIZE - 1, 0 ), (MPARAM) 0L);

       /*
       ** Write filename in edit field
       */
       WinSetDlgItemText( hWnd, EDIT_FILE_OVR, (PSZ) pddc->pdv->szDestnFile );

       /*
       ** Highlight filename
       */
       i = 0;

       while (*(pddc->pdv->szDestnFile + i))
       {
         i++;
       }
       WinSendDlgItemMsg( hWnd, EDIT_FILE_OVR, EM_SETSEL,
                          (MPARAM) MPFROM2SHORT( (SHORT) 0, (SHORT) i ),
                          (MPARAM) 0L );

       /*
       ** Center the dialog box in the middle of the screen
       */
       WinQueryWindowRect( HWND_DESKTOP, &rclScreen );
       WinQueryWindowRect( hWnd, &rclDialog );
       sWidth = (SHORT) (rclDialog.xRight - rclDialog.xLeft);
       sHeight = (SHORT) (rclDialog.yTop - rclDialog.yBottom);
       sBLCx = ((SHORT) rclScreen.xRight - sWidth) / 2;
       sBLCy = ((SHORT) rclScreen.yTop - sHeight) / 2;
       WinSetWindowPos( hWnd, HWND_TOP, sBLCx, sBLCy, 0, 0, SWP_MOVE );
       return 0L;             /* to retain the window focus                  */
       break;

  default:               /* the action as recommended by PM manual      */
    return ((ULONG) WinDefDlgProc( hWnd, uMsg, mp1, mp2 ));
  }
  return 0L;
}

/***************************************************************************
 *
 * FUNCTION NAME = UserFileInvalid
 *
 * DESCRIPTION   = To respond to commands received from user input. User
 *                 can click "OK" or "Cancel", and change file name entry
 *                 field.
 *
 * INPUT         = hWnd
 *                 uMsg
 *                 mp1
 *                 mp2
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = 0L
 *
 * RETURN-ERROR  = NONE
 *
 ****************************************************************************/

ULONG EXPENTRY UserFileInvalid( HWND hWnd, SHORT uMsg, MPARAM mp1, MPARAM mp2 )
{
  PDDC  pddc;
  RECTL rclScreen, rclDialog;
  SHORT sWidth, sHeight, sBLCx, sBLCy;
  SHORT i;

  switch (uMsg)
  {
  case WM_COMMAND:
       pddc = (PDDC) WinQueryWindowULong( hWnd, QWL_USER );

       switch (LOUSHORT(mp1))
       {
       case MBID_OK:
            WinQueryDlgItemText( hWnd, EDIT_FILE_INV,
                                 sizeof( pddc->pdv->szDestnFile ),
                                 (PSZ) pddc->pdv->szDestnFile );
            WinDismissDlg( hWnd, MBID_OK );
            break;

       case MBID_CANCEL:
            WinDismissDlg( hWnd, MBID_CANCEL );
            break;

       default:
            break;
       }
       break;

  case WM_INITDLG:
       pddc = (PDDC) mp2;

       /*
       ** store this data address so that it can be retrieved elsewhere
       */
       if (!WinSetWindowULong( hWnd, QWL_USER, (ULONG) (PDDC) pddc ))
       {
         break;
       }

       /*
       ** Write filename in edit field
       */
       WinSetDlgItemText( hWnd, EDIT_FILE_INV, (PSZ) pddc->pdv->szDestnFile );

       /*
       ** Highlight filename
       */
       i = 0;

       while (*(pddc->pdv->szDestnFile + i))
       {
         i++;
       }
       WinSendDlgItemMsg( hWnd, EDIT_FILE_INV, EM_SETSEL,
                          (MPARAM) MPFROM2SHORT( (SHORT) 0, (SHORT) i ),
                          (MPARAM) 0L);

       /*
       ** Center the dialog box in the middle of the screen
       */
       WinQueryWindowRect( HWND_DESKTOP, &rclScreen );
       WinQueryWindowRect( hWnd, &rclDialog );
       sWidth = (SHORT) (rclDialog.xRight - rclDialog.xLeft);
       sHeight = (SHORT) (rclDialog.yTop - rclDialog.yBottom);
       sBLCx = ((SHORT) rclScreen.xRight-sWidth) / 2;
       sBLCy = ((SHORT)rclScreen.yTop - sHeight) / 2;
       WinSetWindowPos( hWnd, HWND_TOP, sBLCx, sBLCy, 0, 0, SWP_MOVE );
       return 0L;
       break;

  default:               /* the action as recommended by PM manual      */
       return ((ULONG) WinDefDlgProc( hWnd, uMsg, mp1, mp2 ));
  }
  return 0L;
}
