/*DDK*************************************************************************/
/*                                                                           */
/* 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 = GPLTHRD.H
 *
 * DESCRIPTION = Public output thread header for genplib.lib
 *
 *
 * VERSION = V1.0
 * DATE    = 02/18/94
 * AUTHOR  = MarkV
 *
 *
 * FUNCTIONS
 *
 *
 *
 *
 ******************************************************************************
 * NOTES
 ******************************************************************************
 *  GplThreadCreateInstance(HMCB, HMOD, HTHREAD*) - GplThreadInitalize() creates
 *       and initializes the thread instance data.  This call should be made
 *       at Enable(FillPhysicalDeviceBlock) after the creation of
 *       a heap by calling MemoryCreateInst().  The HMCB returned by
 *       MemoryCreateInst() will be stored in the thread instance data
 *       and used for small( Lessthan 2k ) memory objects needed by
 *       the output thread.  Therefore, you must not destroy the heap
 *       with MemoryDeleteInst() until you have deleted the thread instance
 *       with a call to GplThreadDeleteInstance().  For every call to
 *       GplThreadCreateInstance() there must be a corresponding call to
 *       GplThreadDeleteInstance() at Enable(BeginCloseDC).
 *       Note: You can have multiple thread instances if you wish
 *             to use multiple threads at the same time. For any
 *             thread instance you can create and destroy a thread
 *             multiple times.
 *     Parameters:
 *       HMCB - Handle to initialized memory control block.
 *              see MemoryCreateInst(). This handle must be active
 *              until GplThreadDeleteInstance has been called.
 *       HMODULE - Callers module handle.
 *       HTHREAD* - Pointer to a thread handle. The thread instance
 *              handle is returned at the address of the pointer.
 *              The calling code must store the handle for subsequent
 *              Thread calls.
 *     Directions:
 *              Add the following variables to your pDDC(DC instance data)
 *              Structure:
 *                 HMCB hMcb;
 *                 HTHREAD hThread
 *
 *              Add the following includes to the top of your
 *              enable c file:
 *                 #define INCL_GENPLIB_THREAD
 *                 #define INCL_GENPLIB_MEMORY
 *                 #include "genplib.h"
 *
 *              Add the following Calls to your Enable(FillPhysicalDeviceBlock)
 *              function:
 *                  pDDC->hMcb = MemoryCreateInst( ULONG, ULONG, ULONG, ULONG );
 *                  GplThreadCreateInstance(pDDC->hMcb, &pDDC->hThread);
 ******************************************************************************
 *  GplThreadDeleteInstance(HTHREAD*) - This call deletes the semaphores and
 *              and instance data used by the driver. The HTHREAD
 *              parameter is uptated to NULL. This call should be made
 *              at Enable(BeginCloseDC) befor the heap(HMCB) is
 *              deleted.
 *     Parameters:
 *       HTHREAD* - Pointer to a thread handle. The thread instance
 *              handle is set to NULL and is not valid after the call.
 *     Directions:
 *              Add the following Calls to your Enable(FillPhysicalDeviceBlock)
 *              function:
 *                  GplThreadDeleteInstance(&pDDC->hThread);
 *                  pDDC->hMcb = MemoryDeleteInst(pDDC->hMcb);
 ******************************************************************************
 *  GplThreadStart(HTHREAD,LHANDLE,HFILE,ULONG,USHORT, PSZ,PSZ,PSZ,PSZ,LONG)-
 *             This call creates a thread or updates thread parameters if
 *             called again for the same thread.  This call assumes that
 *             a LHANDLE-hSpooler(spooler handle) or HFILE-hDev(File handle)
 *             has been opened.  You should open a spooler handle if the
 *             data is to be queued with SplQMWrite() or a file handle
 *             if the data is to be written to the device with PrtWrite().
 *             Note: Calling GplThreadStart a second or consecutive time
 *             without calling GplThreadEnd() update the thread parameters
 *             without creating a new thread.
 *     Parameters:
 *        HTHREAD-hThread    Handle to thread instance
 *                           data.  Thread must
 *                           be initialized with a call
 *                           to GplThreadCreateInstance() to
 *                           obtain this handle.
 *        LHANDLE-hSpooler   Null or Spooler handle.
 *                           Pass in a spooler handle
 *                           if output is going to the
 *                           spool queue. The handle returned
 *                           from SplQmOpen().
 *        HFILE-hDev         Null or Device handle.
 *                           Pass in a Device handle
 *                           if output is going to the
 *                           device. The handle returned
 *                           from PrtOpen().
 *        ULONG-ulBufferSize Size of buffers to use.
 *                           if either usBufferSize or
 *                           usMaxBuffers are NULL we will
 *                           assign defaults.
 *        USHORT-usMaxBuffers Max number of buffers to use.
 *
 *                           Abort suff: To accommoate a wide varity
 *                           of printers the abort sequence work as
 *                           follows:
 *                           First if the aborted buffer contained
 *                           binary data (THREAD_DT_BINARY was set on
 *                           GplThreadOutput) and a AbortChar and
 *                           AbortCharCount was supplied, the AbortChar
 *                           will be sent the AbortCharCount times.
 *                           Next, If we have a AbortBuffer it
 *                           will always be sent.
 *                           Next if an AbortString was supplied it will
 *                           be sent.
 *        UCHAR-ucAbortChar  Character to send before the
 *                           abort string.  Some devices
 *                           require that a large buffer
 *                           of nulls be sent to take the
 *                           device out of graphics mode
 *                           before sending the abort
 *                           string.
 *       ULONG-ulAboutCharCount # of ucAbortChar's to send
 *                           to send to the device.
 *       ULONG -ulAbortBufferSize - Abort buffer size in bytes.
 *       PBYTE -pbAbortBuffer - Pointer to a buffer to send when
 *                           aborting a job. This buffer is not
 *                           copied by the thread code. Therefore, it
 *                           must not be deleted util after GplThreadEnd.
 *       PSZ-pszAbortString String to send when aborting a job.
 *       PSZ-pszLogAddress  Ptr to string containing the logical address.
 *       PSZ-pszWriteError  Write error prompt string for splmessagebox.
 *       PSZ-pszDeviceDescription- Pointer to the device description string.
 *       LONG-lDCType    DC type
 *     Directions:
 *              Add the following includes to the top of the
 *              C file which contains your output function:
 *                 #define INCL_GENPLIB_THREAD
 *                 #define INCL_GENPLIB_MEMORY
 *                 #include "genplib.h"
 *              Add code to open your Spool File with SplQmOpen the job
 *              is OD_QUEUED or open the output file or device with PrtOpen
 *              if the job is OD_DIRECT.  Then Create the Thread with a
 *              call to Thread_Create(). Note: if you call GplThreadStart()
 *              a second or consecutive time without making a  coresponding
 *              call to Thread_End() the thread paramaters will be updated
 *              without creating a new thread.
 *           GplThreadStart(pPDevice->pOutputInfo,
 *                0L, 0,  // buffer size and count-take defaults
 *                 '0', 0,        // abort char and repeate count
 *                 0, (PBYTE)NULL // abort buffer size and ptr
 *                 vpszAbortString,
 *                 pPDevice->pszLogAddress,
 *                 szDeviceDescription,
 *                 pPDevice->lDcType);
 *
 *
 *
 *
 *
 *
 ******************************************************************************
 * GplThreadOutput(HTHREAD, PBYTE, ULONG, ULONG)- Function gives data to
 *                 the async output thread.
 *     Parameters:
 *           HTHREAD-hThread Handle to thread instance data.  Thread must
 *                           be initialized with a call to GplThreadCreateInstance()
 *                           and created with a call to GplThreadStart()
 *                 PBYTE     ptr to bytes of data
 *                 ULONG     Count of bytes
 *                 ULONG     FLAGS for datatype passed in
 *                           THREAD_DT_PRINTERLANGUAGE  0x01
 *                              Data is printer language commands
 *                              and requires only an abort string
 *                              to be sent when aborting this
 *                              buffer.
 *                              See (pszAbortString)  GplThreadStart
 *                           THREAD_DT_BINARY           0x02
 *                              Data is Binary Data(RASTER)
 *                              and requires a series
 *                              series of bytes be sent to
 *                              insure the printer is not in
 *                              binary transfer mode before the
 *                              abort string is sent.
 *                              See (ucAbortChar) and
 *                              (ulAboutCharCount) on
 *                              GplThreadStart
 *
 *
 *
 ******************************************************************************
 *  GplThreadEnd(HTHREAD)-Causes the thread to terminate and then frees
 *                 its stack and output buffers. This function will wait
 *                 for all buffers to be written before deleting the thread.
 *     Parameters:
 *           HTHREAD-hThread Handle to thread instance data.  Thread must
 *                           be initialized with a call to GplThreadCreateInstance()
 *                           and created with a call to GplThreadStart()
 *
 ******************************************************************************
 *  GplThreadAbortDoc(HTHREAD)- Calling this function causes
 *                 the thread To through away all buffered data and send
 *                 a termination string to the device.  All output data will
 *                 discarded until GplThreadResetAbortDoc() is called.
 *                 Note: This call is valid prior to calling GplThreadStart().
 *                 If called prior to GplThreadStart() it will cause the next
 *                 thread created with the save HTHREAD to abort all output.
 *
 *     Parameters:
 *           HTHREAD-hThread Handle to thread instance data.  Thread must
 *                           be initialized with a call  to
 *                           GplThreadCreateInstance() to obtain this handle.
 *
 *
 ******************************************************************************
 *  GplThreadResetAbortDoc(HTHREAD)-This Function resets the previous AbortDoc.
 *                 This function may have to wait
 *                 for the previous job to be aborted before it can reset
 *                 the Abort Document information held by the thread code.
 *
 *     Parameters:
 *           HTHREAD-hThread Handle to thread instance data.  Thread must
 *                           be initialized with a call  to
 *                           GplThreadCreateInstance() to obtain this handle.
 *
 ******************************************************************************
 * GplThreadFlushBuffer (HTHREAD, BOOL)- This function can
 *                 will put the contents of the local
 *                 accumulation buffer on the output thread to ensure
 *                 that important printer commands are not waiting for more
 *                 data to be written.  If the Wait parameter is TRUE
 *                 the call will not return until all data has been written.
 *
 *     Parameters:
 *           HTHREAD-hThread Handle to thread instance data.  Thread must
 *                           be initialized with a call  to
 *                           GplThreadCreateInstance() to obtain this handle.
 *           BOOL-bWait TRUE Wait for all data to be written.
 *                      FALSE Put the current buffer on the output
 *                         buffer queue and return immediately.
 *
 ******************************************************************************
 ***************************************************************************
 * GplThreadHookDeviceWrites(HTHREAD,PFN)
 *                 Function allows the caller to hook all writes
 *                 to the device from the thread code. The hook
 *                 function must behave exactly like PrtWrite.
 *
 *     Parameters:
 *                 HTHREAD hThread- handle to the thread instance data,
 *                      which is a POUTPUTINFO pOutputinfo.
 *                      A GplThreadStart must be issued prior to
 *                      subclassing (hooking) the thread writes.
 *
 *                 PFN pfnPrtWriteHook - Pointer to the users
 *                      function for PrtWrite
 *                 PVOID pvPrtWriteHookPDDC - Callers PDDC. Used
 *                       as the first param to the hooked PrtWrite
 *
 * RETURN-NORMAL = BOOL TRUE=Successful
 *
 **************************************************************************
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

/*
** fulDataType flags for GplThreadOutput
*/
#define  THREAD_DT_PRINTERLANGUAGE  0x01  /* Data is printer language commands*/
                                          /* and requires only an abort string*/
                                          /* to be sent when aborting this    */
                                          /* buffer.                          */
                                          /* See (pszAbortString              */
                                          /* GplThreadStart                   */
#define  THREAD_DT_BINARY           0x02  /* Data is Binary Data(RASTER)      */
                                          /* and requires a series            */
                                          /* series of bytes be sent to       */
                                          /* insure the printer is not in     */
                                          /* binary transfer mode before the  */
                                          /* abort string is sent.            */
                                          /* See (ucAbortChar) and            */
                                          /* (ulAboutCharCount) on            */
                                          /* GplThreadStart                   */

typedef PVOID HTHREAD;

/*
** extern interface to output thread
*/
extern BOOL APIENTRY GplThreadCreateInstance(HMCB, HMODULE, HTHREAD*);
extern BOOL APIENTRY GplThreadStart(HTHREAD,LHANDLE,HFILE,ULONG,USHORT,
                                UCHAR,ULONG,ULONG,PBYTE,PSZ,PSZ,PSZ,PSZ,LONG);
extern BOOL APIENTRY GplThreadOutput(HTHREAD, PBYTE, ULONG, ULONG);
extern BOOL APIENTRY GplThreadEnd(HTHREAD);
extern BOOL APIENTRY GplThreadDeleteInstance(HTHREAD*);
extern BOOL APIENTRY GplThreadAbortDoc(HTHREAD);
extern BOOL APIENTRY GplThreadFlushBuffer (HTHREAD, BOOL);
extern BOOL APIENTRY GplThreadResetAbortDoc(HTHREAD);
extern BOOL APIENTRY GplThreadHookDeviceWrites(HTHREAD,PFN,PVOID);


