⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printer.cpp

📁 HP喷墨打印机驱动代码 HP内部资料! 珍贵 珍贵 珍贵
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						err = Send (InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR]);					}				}			}		}		else		{			scratchLen = sprintf (scratch, "\033*b%uW", InputRaster->rastersize[COLORTYPE_COLOR]);			err = Send ((const BYTE*) scratch, scratchLen);			if (err == NO_ERROR)			{				err = Send (InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR]);			}		}    }    else    {        scratchLen = sprintf (scratch, "\033*b%uV", InputRaster->rastersize[COLORTYPE_COLOR]);		err = Send ((const BYTE*) scratch, scratchLen);		if (err == NO_ERROR)		{			err = Send (InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR]);		}    }    return err;}DRIVER_ERROR Printer::Send(    const BYTE* pWriteBuff){    ASSERT(pWriteBuff);    int len = strlen((const char*)pWriteBuff);    return Send(pWriteBuff,len);} //Send/* *  Function name: Printer::Send * *  Owner: Darrell Walker * *  Purpose:  Encapsulate error handling generated by performing I/O * *  Called by: * *  Calls made: WritePort(), GetStatus(), BusyWait(), ParseError(), *              DisplayPrinterStatus(), YieldToSystem() * *  Parameters on entry: pJob is a pointer to the current JOBSTRUCT, *                      pWriteBuff is a pointer to the data the *                      caller wishes to send to the pritner, *                      wWriteCount is the number of bytes of *                      pWriteBuff to send * *  Parameters on exit: Unchanged * *  Side effects: Sends data to the printer, may update print dialog, *              may change pJob->InSlowPollMode, *              pJob->ErrorTerminationState * *  Return Values: NO_ERROR or JOB_CANCELED or IO_ERROR * *  Comments: (TJL) This routine now has functionality to attempt iterating *      through wWriteCount bytes of data (until we hit slow poll mode) *      before sending PCL cleanup code.  This still leaves the possibility of *      prematurely exiting with an incomplete raster, but gives I/O a fighting chance *      of completing the raster while also protecting from a bogged down slow poll phase *      which would prevent a timely exit from CANCEL.  A JobCanceled flag is used *      because JOB_CANCELED cannot be maintained by write_error through the while *      loop since it will be overwritten by next ToDevice. * */DRIVER_ERROR Printer::Send(    const BYTE* pWriteBuff,    DWORD dwWriteCount){    ASSERT(pWriteBuff);    DRIVER_ERROR    write_error = NO_ERROR;    DWORD           residual = 0;    const BYTE *    pWritePos = NULL;    BOOL            error_displayed = FALSE;    BYTE            status_reg = 0;    DISPLAY_STATUS  eDisplayStatus = DISPLAY_PRINTING;    BOOL            JobCanceled = FALSE;  // see comments in function header    // these are just an abstraction layer - buffered vs. non-buffered    const BYTE *    pBuffer = pWriteBuff;    DWORD           dwSendSize = dwWriteCount;////////////////////////////////////////////////////////////////#ifdef NULL_IO    // test imaging speed independent of printer I/O, will not    // send any data to the device    return NO_ERROR;#endif////////////////////////////////////////////////////////////////    if (ErrorTerminationState)  // don't try any more IO if we previously    {        return JOB_CANCELED;    // terminated in an error state    }    if (EndJob == FALSE && dwWriteCount == 0)    // don't bother processing    {        return NO_ERROR;                         //  an empty Send call    }#ifdef APDK_BUFFER_SEND    DWORD BytesToWrite = dwWriteCount;    do    {        // we should bypass the buffering for a large Send, but don't lose what may already be buffered        if ( (BytesToWrite >= iBuffSize) && (iCurrBuffSize == 0) )        {            pBuffer = pWriteBuff+(dwWriteCount-BytesToWrite);            dwSendSize = BytesToWrite;            BytesToWrite = 0;  // this is checked for at the end of the outer loop        }        else // we will buffer this data        {            // if it'll fit then just copy everything to the buffer            if (BytesToWrite <= DWORD(iBuffSize-iCurrBuffSize))            {                memcpy((void*)(pSendBuffer+iCurrBuffSize),                    (void*)(pWriteBuff+(dwWriteCount-BytesToWrite)),BytesToWrite);               iCurrBuffSize += BytesToWrite;               BytesToWrite = 0;            }              else // copy what we can into the buffer, we'll get the rest later            {              memcpy((void*)(pSendBuffer+iCurrBuffSize),                (void*)(pWriteBuff+(dwWriteCount-BytesToWrite)),                iBuffSize-iCurrBuffSize);                BytesToWrite -= (iBuffSize-iCurrBuffSize);                iCurrBuffSize = iBuffSize;            }            // if the buffer is now full (ready-to-send) or if we're at            // the end of the job, then send what we have in the buffer.            // otherwise just break (the buffer isn't ready to send)            if ( (EndJob == FALSE) && (iCurrBuffSize != iBuffSize) )            {                break;  // we're not ready to send yet            }            else // send this buffered data            {                pBuffer = pSendBuffer;                dwSendSize = iCurrBuffSize;            }		}#endif    // initialize our 'residual' to the full send size    residual = dwSendSize;    if (bCheckForCancelButton &&        (ulBytesSentSinceCancelCheck >= CANCEL_BUTTON_CHECK_THRESHOLD) )    {        ulBytesSentSinceCancelCheck = 0;        char* tmpStr;        BYTE DevIDBuffer[DevIDBuffSize];        DRIVER_ERROR tmpErr = pSS->GetDeviceID(DevIDBuffer, DevIDBuffSize, TRUE);        if(tmpErr)            return tmpErr;        BOOL cancelcheck=FALSE;        if((tmpStr = strstr((char*)DevIDBuffer + 2,"CNCL")))        {            cancelcheck=TRUE;        }        else        {            int     iVersion = pSS->GetVIPVersion ();            if((tmpStr = strstr((char*)DevIDBuffer + 2,";S:")) &&                iVersion < 6)    // aladdin devID style            {                // point to PrinterState/* *				VIPVersion = DevID Version + 1 - DevID Version no is 2 bytes following ;S: *				Version 00 and 01 report 12 bytes for status info *				Version 02 and onwards, report two additional bytes before pen info */				if (iVersion < 3)				{					tmpStr += 17;   // 3 for ";S:", 2 for version, 12 for features = 17				}				else if (iVersion < 5)				{					tmpStr += 19;	// 17 as above plus 1 for MaxPaperSize, 1 reserved = 19				}                else                {                    tmpStr += 23;   // Crystal added 4 more nibbles                }                BYTE b1=*tmpStr++;                BYTE b2=*tmpStr++;                if (((b1=='0') && (b2=='5')) && iVersion <= 5)     // 05 = cancel                {                    cancelcheck=TRUE;                }            }        }        if (cancelcheck)        {            // Since the printer is now just throwing data away, we can bail            // immediately w/o worrying about finishing the raster so the            // end-of-job FF will work.            ErrorTerminationState = TRUE;            pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);            return JOB_CANCELED;        }    }    // If we have nothing to send, we need to bail to avoid spurious dialogs    //  at the end of the ::send function.  I'd prefer a solution where we don't    //  bail from a while loop but in practice this shouldn't have any ill effects.    if (residual <= 0)    {        return NO_ERROR;    }    while (residual > 0)    // while still data to send in this request    {        DWORD prev_residual = residual;     // WritePort overwrites request                                            // count, need to save        pWritePos = (const BYTE *) &(pBuffer[dwSendSize-residual]);        write_error = pSS->ToDevice(pWritePos, &residual);        // The following error handling code is recommended, but is not supported        // on several current platforms for this reason:  when the printer buffer        // fills and declines more data, the O/S returns a BUSY error in one form        // or another.  The real solution is to allow the code below and have the        // derived pSS->ToDevice functions catch and ignore any BUSY error - only        // returning a real error to ::Send.  The current workaround here is that we        // literally ignore all errors returned from the I/O system and ultimately catch        // them after we've reached our slow poll limit via the slow poll logic below. -TL//        if(write_error != NO_ERROR)//        {//            DBG1("IO_ERROR returned from ToDevice - ABORT!\n");//            ErrorTerminationState = TRUE;//            return write_error;//        }        write_error = NO_ERROR;        eDisplayStatus = DISPLAY_PRINTING;        if (residual == 0) // no more data to send this time        {            if (m_bStatusByPJL)            {                status_reg = (BYTE) DISPLAY_PRINTING;                eDisplayStatus = ParseError (status_reg);                if (eDisplayStatus != DISPLAY_PRINTING)                    write_error = IO_ERROR;            }            // did we want to transition out of slow poll?            if ( (InSlowPollMode != 0) &&                (prev_residual > MIN_XFER_FOR_SLOW_POLL) )            {                InSlowPollMode = 0;                iTotal_SLOW_POLL_Count = 0;            }            if (write_error == NO_ERROR)                break;  // out of while loop        }        // if we are here, WritePort() was not able to        // send the full request so start looking for errors        // decide whether we've waited long enough to check for an error        if (InSlowPollMode > iMax_SLOW_POLL_Count )        {            if (JobCanceled == TRUE)            // Well, I/O didn't finish in time to meet the CANCEL request and avoid            // the SlowPoll threshold.  We have to bail for prompt cancel response.            {                DBG1("Send(SlowPoll): Premature return w/ JOB_CANCELED\n");                ErrorTerminationState = TRUE;                return JOB_CANCELED;            }            DBG1("Printer slow poll times exceeded\n");            // reset counter so we will not pop it next time            InSlowPollMode = 1;            write_error = IO_ERROR;        }        else        {            write_error = NO_ERROR;        }        // are we in slow poll mode?  If so, track our count        if ( (prev_residual - residual) <= MIN_XFER_FOR_SLOW_POLL)        {            InSlowPollMode++;#if defined(DEBUG) && (DBG_MASK & DBG_LVL1)            if (InSlowPollMode == 1)            {                printf("entering slow poll mode\n");            }            else            {                printf("still in slow poll mode, count = %d\n",                                    InSlowPollMode);            }#endif            // give the printer some time to process            if (pSS->BusyWait((DWORD)200) == JOB_CANCELED)            {                DBG1("Send: JOB_CANCELED\n");                JobCanceled = TRUE;                pSS->DisplayPrinterStatus(DISPLAY_PRINTING_CANCELED);            }        }        else        {            // still busy, but taking enough data that            // we are not in slow poll mode            DBG1("Partial Send but not slow poll mode\n");            InSlowPollMode = 0;            iTotal_SLOW_POLL_Count = 0;        }        if (write_error != NO_ERROR || (m_bStatusByPJL && eDisplayStatus != DISPLAY_PRINTING))        // slow poll times exceeded        // the printer isn't taking data so let's see what's wrong...        {            DBG1("Parsing possible error state...\n");            error_displayed = TRUE;            if (m_bStatusByPJL)            {                status_reg = (BYTE) eDisplayStatus;            }            else            {                // go get the status of the printer                if (IOMode.bStatus)                {                    pSS->GetStatusInfo(&status_reg);                }                // determine the error                eDisplayStatus = ParseError(status_reg);            }            switch (eDisplayStatus)            {                case DISPLAY_PRINTING_CANCELED:                        // user canceled in an error state,                        // so we don't want to attempt any                        // further communication with the printer                        ErrorTerminationState = TRUE;                        pSS->DisplayPrinterStatus(eDisplayStatus);                        return JOB_CANCELED;                case DISPLAY_ERROR_TRAP:                case DISPLAY_COMM_PROBLEM:                        // these are unrecoverable cases                        // don't let any more of this job                        // be sent to the printer                        ErrorTerminationState = TRUE;                        pSS->DisplayPrinterStatus(eDisplayStatus);                        // wait for user to cancel the job,                        // otherwise they might miss the                        // error message                        while (pSS->BusyWait(500) != JOB_CANCELED)                        {                                // nothing....                            ;                        }                        return IO_ERROR;                case DISPLAY_TOP_COVER_OPEN:                    pSS->DisplayPrinterStatus(DISPLAY_TOP_COVER_OPEN);                    // wait for top cover to close                    while ( eDisplayStatus == DISPLAY_TOP_COVER_OPEN)                    {                        if (pSS->BusyWait((DWORD)500) == JOB_CANCELED)                        // although we'll leave an incomplete job in the printer,                        // we really need to bail for proper CANCEL response.                        {                            ErrorTerminationState = TRUE;                            return JOB_CANCELED;                        }                        if (m_bStatusByPJL)                        {                            status_reg = (BYTE) eDisplayStatus;                        }                        else                        {                            if (IOMode.bStatus)                            {                                pSS->GetStatusInfo(&status_reg);                            }                        }                        eDisplayStatus = ParseError(status_reg);                    }                    pSS->DisplayPrinterStatus(DISPLAY_PRINTING);                    // Wait for printer to come back online                    if (pSS->BusyWait((DWORD)1000) == JOB_CANCELED)                    // Since the top_cover error HAS been handled, we have                    // the opportunity to finish the raster before we hit                    // the next slowpoll threshold.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -