/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark 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 = prdq_Escape
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                   /* CON3201 */
#define INCL_DOSPROCESS           /* CON3201 */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPIERRORS
#define INCL_DEV
#include <os2.h>
#undef INCL_DOSPROCESS            /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS
#undef INCL_DEV

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS

#define INCL_DEVP
#define INCL_WINP
#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
/* #include <os2p.h>  Changed for DDK release needs to remove PMWINP.H file */
#include <pmwinx.h>
#undef INCL_DEVP
#undef INCL_WINP
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_32                    /* CON3201 */

#define NO_SYS
#define PRDMTYPE_INCL
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef PRDMTYPE_INCL
#undef NO_SYS

#include <prdeextf.h>
#include <prdgextf.h>
#include <prdqextf.h>
#include <prdyextf.h>
#include <prdnextf.h>
#include <prdncone.h>

USHORT prdz_EnterDriver(lpDCI);   /* CON3201 removed pascal from declaration */

/******************************************************************************/
/*  FUNCTION: prdq_Escape                                                     */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"          */
/*                                                                            */
/*  hanDC   DcH;                                                              */
/*  ULONG   ArgEscape;                                                        */
/*  ULONG   ArgInCount;                                                       */
/*  PULONG  ArgInData;                                                        */
/*  PULONG  ArgOutCount;                                                      */
/*  PULONG  ArgOutData;                                                       */
/*  lpDCI   DCIData;                                                          */
/*  ULONG   FunN;                                                             */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function allows access to driver facilities which are not covered by */
/*  the GPI calls.                                                            */
/*                                                                            */
/*  CHANGES:                                                                  */
/*                                                                            */
/*  This area will have to be changed if you wish to provide access to device */
/*  features which will not be accessible through the normal GPI interface.   */
/*  New DEVESC codes will have to be defined and they will have to have an    */
/*  entry here, in the escape 'dispatch table', in the QueryEscSupport        */
/*  function and a routine to perform the function in the escape subroutines  */
/*  module.  The parameters passed via this function to the escape command    */
/*  handlers are very general so most possibilities should be accomodated -   */
/*  look at the handlers in the escape subroutines module for examples of an  */
/*  escape command handler.                                                   */
/******************************************************************************/
ULONG prdq_Escape ( hanDC   DcH,
                    ULONG   ArgEscape,
                    ULONG   ArgInCount,
                    PULONG  ArgInData,
                    PULONG  ArgOutCount,
                    PUSHORT ArgOutData,
                    lpDCI   DCIData,
                    ULONG   FunN)

{
#define TFUNC "prdq_Escape"

    /**************************************************************************/
    /*  Local Variables                                                       */
    /**************************************************************************/
/*  USHORT              Result;           Function call return values         */
    SHORT               Result;        /* CON3203 CHANGED TO SHORT            */

    TRACE4(TFUNC, "Entry", FNULL, 0);
    TRACE8(TFUNC, "Escape Code", &ArgEscape, 1);

#ifdef DEBUG_FSM

    OutputString("Entering DevEscape function - parameters:");
    OutputPair("ArgEscape  : ", ArgEscape, HEX);
    OutputPair("ArgInCount : ", (ULONG)ArgEscape, HEX);
    OutputPair("ArgInData  : ", (ULONG)ArgEscape, HEX);
    OutputPair("ArgOutCount: ", (ULONG)ArgEscape, HEX);
    OutputPair("ArgOutData : ", (ULONG)ArgEscape, HEX);

#endif

    if (ArgEscape == DEVESC_ABORTDOC)
    {

#ifdef DEBUG_FSM

        OutputPair("Initial FSM state   : ", (ULONG)DCIData->State, HEX);
        OutputPrompt(".");

#endif

        Result = prdq_AbortDoc(DcH, ArgInCount, ArgInData, ArgOutCount,
                               ArgOutData, DCIData);

#ifdef DEBUG_FSM

    OutputPair("Return code from AbortDoc : ", (ULONG)Result,  HEX);
    OutputPair("Final FSM state           : ", (ULONG)DCIData->State, HEX);
    OutputPrompt(".");

#endif

        return(Result);
    }
    else
    {
        if (!prdz_EnterDriver(DCIData))
            return((ULONG)ERROR_NEG);  /* CON3203 */

#ifdef DEBUG_FSM
        OutputPair("Initial FSM state   : ", (ULONG)DCIData->State, HEX);
        OutputPrompt(".");
#endif

        /**********************************************************************/
        /*  Select function according to ArgEscape.  See the called functions */
        /*  for a description of their operation.  The parameters required by */
        /*  each function from those passed to prdq_Escape are passed to the  */
        /*  called function cast to the appropriate type.                     */
        /**********************************************************************/
        switch ((USHORT)ArgEscape)
        {
        case DEVESC_QUERYESCSUPPORT:
            Result = prdq_QueryEscSupport(ArgInCount, ArgInData, ArgOutCount,
                                          ArgOutData, DCIData);
            prdm_LeaveDriver(DCIData);
            return((ULONG)Result);   /* CON3203 */
            break;

        case DEVESC_STARTDOC:
#ifdef PRD_TIMING
    DEKHOOK0(A,9,49)
#endif
            Result = prdq_StartDoc(DcH, ArgInCount, ArgInData, ArgOutCount,
                                   ArgOutData, DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,9,C9)
#endif
            break;

        case DEVESC_ENDDOC:
#ifdef PRD_TIMING
    DEKHOOK0(A,9,4A)
#endif
            Result = prdq_EndDoc(DcH, ArgInCount, ArgInData, ArgOutCount,
                                 ArgOutData, DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,9,CA)
#endif
            break;

        case DEVESC_NEWFRAME:
#ifdef PRD_TIMING
    DEKHOOK0(A,8,20)
#endif
            Result = prdq_NewFrame(DcH, ArgInCount, ArgInData, ArgOutCount,
                                   ArgOutData, DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,A0)
#endif
            break;

        case DEVESC_FLUSHOUTPUT:
            Result = prdq_FlushOutput(DcH, ArgInCount, ArgInData, ArgOutCount,
                                      ArgOutData, DCIData);
            break;

        case DEVESC_RAWDATA:
#ifdef PRD_TIMING
    DEKHOOK0(A,8,23)
#endif
            Result = prdq_RawData(ArgInCount, (PCHAR)ArgInData, DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,A3)
#endif
            break;
        case DEVESC_STD_JOURNAL:
            Result = prdq_JournalData(ArgInCount, ArgInData, ArgOutCount,
                                      ArgOutData, DCIData);
            break;

        case DEVESC_SETMODE:
#ifdef PRD_TIMING
    DEKHOOK0(A,8,25)
#endif
            Result = prdq_SetMode(ArgInCount, ArgInData, ArgOutCount,
                                  ArgOutData, DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,8,A5)
#endif
        default:

            /******************************************************************/
            /*  The default case is when an escape code is not recognised and */
            /*  is therefore not supported.                                   */
            /******************************************************************/
            LOGERR(TFUNC, "Escape not implemented", FNULL, 0,
                   PMERR_ESC_CODE_NOT_SUPPORTED);
            prdm_LeaveDriver(DCIData);
            return((ULONG)((LONG)DEVESC_NOTIMPLEMENTED));
        }
    }

    /**************************************************************************/
    /*  Return the result of the escape function called from the switch       */
    /*  statement.                                                            */
    /**************************************************************************/
    TRACE4(TFUNC,"Return Result", &Result, 1);

#ifdef DEBUG_FSM
    OutputPair("Return code from DevEscape: ", (ULONG)Result,  HEX);
    OutputPair("Final FSM state           : ", (ULONG)DCIData->State, HEX);
    OutputPrompt(".");
#endif

    prdm_LeaveDriver(DCIData);

    if (Result != OK)
/*      return((ULONG)((LONG)((SHORT)ERROR_NEG)));    CON3203 */
        return((ULONG)ERROR_NEG);
    else
        return((ULONG)OK);

}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prdq_QueryEscSupport                                            */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  ULONG   ArgInCount;   Unused parameter                                    */
/*  PULONG  ArgInData;    Pointer to the escape code to query                 */
/*                        query                                               */
/*  PULONG  ArgOutCount;  Unused parameter                                    */
/*  PULONG  ArgOutData;   Unused parameter                                    */
/*  lpDCI   DCIData;      Unused parameter                                    */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function returns whether or not an escape code is supported by       */
/*  prdq_Escape.                                                              */
/******************************************************************************/
SHORT prdq_QueryEscSupport( ULONG   ArgInCount,       /* CON3203 */
                             PULONG  ArgInData,
                             PULONG  ArgOutCount,
                             PUSHORT ArgOutData,
                             lpDCI   DCIData)

{
#define TFUNC "prdq_QryEscSupp"

    TRACE4(TFUNC, "Entry", FNULL, 0);

#ifdef DEBUG_FSM

    OutputString("DevEsc Query Escape Support");

#endif

    /**************************************************************************/
    /*  If the function is supported then return DEVESC_OK otherwise return   */
    /*  DEVESC_NOTIMPLEMENTED.  ???                                           */
    /**************************************************************************/
    TRACE8(TFUNC, "ESC function", ArgInData, 1);
    switch ((USHORT)(*ArgInData))
    {
    case DEVESC_QUERYESCSUPPORT:
    case DEVESC_STARTDOC:
    case DEVESC_ENDDOC:
    case DEVESC_NEWFRAME:
    case DEVESC_ABORTDOC:
    case DEVESC_FLUSHOUTPUT:
    case DEVESC_RAWDATA:
    case DEVESC_STD_JOURNAL:
    case DEVESC_SETMODE:
        return((ULONG)((LONG)OK));
    default:
        return((ULONG)DEVESC_NOTIMPLEMENTED);
    }
}
#undef TFUNC
