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

📄 minidlg.c

📁 打印机驱动源码for WIN98
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*                                                                           *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY     *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE       *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR     *
* PURPOSE.                                                                  *
*                                                                           *
* Copyright (C) 1993-95  Microsoft Corporation.  All Rights Reserved.       *
*                                                                           *
****************************************************************************/

#define PRINTDRIVER
#define BUILDDLL
#define MAXDELAY 30
#define SP_OK 1
#define MAXBYTES 384
#define STARTLINE 10
#include "print.h"
#include "gdidefs.inc"
#include "bitmap.h"
#include "mdevice.h"
#include "unidrv.h"

short OutOnePage(LPEXTPDEV lpXPDV);

extern char *rgchModuleName;    // global module name

char szSection[8] = "BITMAP,";

BYTE inp(WORD port)
{
    BYTE indata;

    _asm mov dx,port;
    _asm in al,dx;
    _asm mov indata,al;
    return indata;
}

void outp(WORD port,BYTE odata)
{
    _asm mov dx,port;
    _asm mov al,odata;
    _asm out dx,al;
}

void _disable(void)
{
    _asm cli;
}

void _enable(void)
{
    _asm sti;
}


DWORD RealTime(void)
{
   BYTE sec,min,hour;
   WORD i;

   for (i=0; i<8000; i++) {
      _disable();
      outp(0x70,0xa);
      if (!(inp(0x71) & 0x80)) {
	outp(0x70,4);
	hour=(BYTE)inp(0x71);
	outp(0x70,2);
	min=(BYTE)inp(0x71);
	outp(0x70,0);
	sec=(BYTE)inp(0x71);
	_enable();
	hour=(BYTE)((hour & 0xf)+(hour>>4)*10);
	min=(BYTE)((min & 0xf)+(min>>4)*10);
	sec=(BYTE)((sec & 0xf)+(sec>>4)*10);
	return (3600L*hour+60*min+sec);
      }
      _enable();
   }

   return 0xffffffff;
}

void DelayTM(WORD ms)
{
  DWORD timecnt;

  timecnt=GetTickCount();
  for (; (GetTickCount()-timecnt)<(DWORD)ms; );
}

void delay()
{
   int i;
   for (i=0; i<2048; i++)
     if (i=i);
}

short CheckPort(LPEXTPDEV lpXPDV)
{
   int port;

   for (port=0x280; port<0x2c0; port +=0x10) {
       outp(port,0xe0);
       if (inp(port) & 2) {
	   outp(port,0xe2);
	   if (inp(port) & 2) {
	      outp(port,0xe8);
	      if (inp(port) & 2) {
		 outp(port,0xea);
		 if (!(inp(port) & 2)) {      //find port
		    outp(port,0xe0);
		    lpXPDV->port=port;
		    return SP_OK;
		 }
	      }
	   }
       }
   }

   MessageBox(NULL,"Printer Card not Found!",
	  "CopyPrinter Driver",
	   MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL);
   lpXPDV->func=100;
   return SP_ERROR;
}

BOOL SetupComm(LPEXTPDEV lpXPDV)
{
   WORD port;

   port=lpXPDV->port;
   outp(port,0xe2);
   delay();
   outp(port+1,0);
   delay();
   outp(port+1,0);
   delay();
   outp(port+1,0);
   delay();
   outp(port+1,0x40);
   delay();
   outp(port+1,0xce);
   delay();
   outp(port+1,7);
   delay();
   delay();
   if ((inp(port+1) & 5)!=5)
     return FALSE;
   outp(port,0xe0);
   delay();
   return TRUE;
}

BOOL StatusRead(LPEXTPDEV lpXPDV)
{
  DWORD tmOld,tmCur;
  char ch;
  WORD port;

   port=lpXPDV->port;

   tmOld=RealTime();
   for (;;) {
     if ((tmCur=RealTime())<tmOld)
       tmCur +=24*3600L;
     if (tmCur-tmOld>5) {
	outp(port,0xe0);
	return FALSE;
     }
     outp(port,0xe2);
     delay();
     ch=(char)inp(port+1);
     delay();
     if (ch & 0x38) {
	outp(port+1,0x17);
	delay();
	outp(port,0xe0);
	return FALSE;
     }
     if (ch & 2) {
	outp(port,0xe0);
	delay();
	ch=(char)inp(port+1);
	delay();
	return TRUE;
     }
   }
   return FALSE;
}

void StatusWrite(LPEXTPDEV lpXPDV,char wdata)
{
   WORD port;

   port=lpXPDV->port;
   outp(port,0xe2);
   delay();
   for (; !(inp(port+1) & 1) ;);
   delay();
   outp(port,0xe0);
   delay();
   outp(port+1,wdata);
   delay();
}

void ClrLine(LPEXTPDEV lpXPDV)
{
    WORD i, port;

    port=lpXPDV->port;
    
    _disable();
    outp(port+3,0);
    inp(port+3);
    for (i=0; i<MAXBYTES; i++)
	outp(port+2,0);
    outp(port+3,0);
    inp(port+2);
    for (i=0; i<MAXBYTES; i++)
	outp(port+2,0);
    _enable();
}
   
BOOL Shickhand(LPEXTPDEV lpXPDV)
{
   char ch;
   WORD port;

   if (!SetupComm(lpXPDV))
     return FALSE;

   port=lpXPDV->port;
   outp(port,0xe2);
   delay();
   ch=(char)inp(port+1);
   delay();
   if (ch & 0x38) {
      outp(port+1,0x17);
      delay();
      ch=(char)inp(port+1);
      delay();
   }
   if (ch & 2) {
      inp(port+1);
      delay();
      inp(port+1);
      delay();
   }
   StatusWrite(lpXPDV,(char)0xa0);
   StatusWrite(lpXPDV,(char)0x14);
   if (!StatusRead(lpXPDV))
     return FALSE;
   StatusWrite(lpXPDV,(char)0xb);
   if (!StatusRead(lpXPDV))
     return FALSE;
   if (!StatusRead(lpXPDV))
     return FALSE;
   StatusWrite(lpXPDV,(char)0x88);
   StatusWrite(lpXPDV,(char)0x5);
   if (inp(lpXPDV->port) & 0x80)
       return FALSE;
   return TRUE;
}

short OutOnePage(LPEXTPDEV lpXPDV)
{
   WORD i, j, wWidthBytes,dwLine,lfBytes=0;
   BYTE _huge *p;
   DWORD tmCur,tmOld;
   WORD port,dport,sport;
   signed char ch,c;
   WORD oldint21,oldinta1;
   WORD iDs;

   // get pointer to our private data stored in UNIDRV's PDEVICE
   dwLine=(WORD)(lpXPDV->dwTotalScans);
   wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);

   if (MAXBYTES>wWidthBytes)
     lfBytes=(MAXBYTES-wWidthBytes)/2;

   ClrLine(lpXPDV);
   ClrLine(lpXPDV);

   for (;!Shickhand(lpXPDV);) {
       MessageBeep(-1);
       if (MessageBox(NULL,"Printer not Ready!",
		"CopyPrinter Driver",
		 MB_RETRYCANCEL | MB_ICONSTOP | MB_SYSTEMMODAL)==IDCANCEL) {
	   lpXPDV->func=100;
	   return SP_USERABORT;
       }
   }

   port=lpXPDV->port;
   dport=port+2;
   sport=port+3;

   outp(port,0xe4);
     DelayTM(500);
   outp(port,0xf8);
     DelayTM(100);

   tmOld=RealTime();
   for (; inp(port) & 8 ;) {
     if ((tmCur=RealTime())<tmOld)
       tmCur +=24*3600L;
     if (tmCur-tmOld>MAXDELAY) {
	lpXPDV->func=100;
	return SP_ERROR;
     }
   }

   p=lpXPDV->lpScanBuf;
   _disable();
   oldint21=inp(0x21);
   oldinta1=inp(0xa1);
   outp(0x21,0xff);
   outp(0xa1,0xff);
   p=lpXPDV->lpScanBuf;
   outp(port,0xf9);

   //For 5320 & 5323 Clear Begin Lines
   //For 5360 & 5385 to  Page Start Position

   outp(sport,0);
   for (i=0; i<STARTLINE; i++) {
      for (; !(inp(port) & 1);) {
	if ((tmCur=RealTime())<tmOld)
	tmCur +=24*3600L;
	if (tmCur-tmOld>MAXDELAY) {
	   outp(0x21,oldint21);
	   outp(0xa1,oldinta1);
	   _enable();
	   lpXPDV->func=100;
	   return SP_ERROR;
	}
      }
      outp(sport,0);
      for (j=0; j<MAXBYTES; j++)
	outp(dport,0);
   }

   for (i=0; !(inp(port) & 8) && i < dwLine; i++) {

      for (; !(inp(port) & 1);) {
	if ((tmCur=RealTime())<tmOld)
	tmCur +=24*3600L;
	if (tmCur-tmOld>MAXDELAY) {
	   outp(0x21,oldint21);
	   outp(0xa1,oldinta1);
	   _enable();
	   lpXPDV->func=100;
	   return SP_ERROR;
	}
      }
      
      outp(sport,0);
      outp(sport,0);
      //Output Left space

      for (j=0; j<lfBytes; j++) {
	outp(dport,0);
	if (j==j) j=j;
	if (j==j) j=j;
      }

      for (iDs=0; iDs<wWidthBytes;) {
	  ch=*p++;
	  if( ch >= 0 && (int)ch <= 127) {
	     iDs +=(int)ch+1;
	     for (; ch > -1; ch--) {
		outp(dport,*p++);
		if (iDs==iDs) iDs=iDs;
		if (iDs==iDs) iDs=iDs;
	     }
	  }
	  else 
	      if ( ch < 0 && ch>=-127 ) {
		  iDs +=1-(int)ch;
		  c=*p++;
		  for( ; ch<1 ; ch++) {
		     outp(dport,c);
		     if (iDs==iDs) iDs=iDs;
		     if (iDs==iDs) iDs=iDs;
		  }
	      }
	      else {
		   outp(0x21,oldint21);
		   outp(0xa1,oldinta1);
		   _enable();
		   lpXPDV->func=100;
		   return SP_ERROR;
	      }
      }
   }
   outp(0x21,oldint21);
   outp(0xa1,oldinta1);
   _enable();
   outp(port,0xe0);
   if (MessageBox(NULL,"Continue ... ?","CopyPrinter Driver",
	     MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL)==IDNO) {
       lpXPDV->func=100;
       return SP_USERABORT;
   }
   return SP_OK;

} //*** DumpScans

short Alloc(LPEXTPDEV lpXPDV)
{
   WORD wBytes=0,Mod;
   WORD wWidthBytes;

   wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);

   if (Mod=(WORD)(lpXPDV->dwTotalScans%32)) {

       Mod=32-Mod;
       wBytes=Mod*wWidthBytes;

       if ((lpXPDV->dwTotalScanBytes + wBytes) > lpXPDV->dwScanBufSize)
       {
	  HANDLE hTemp;

	  lpXPDV->dwScanBufSize = lpXPDV->dwTotalScanBytes+wBytes;

	  hTemp = GlobalReAlloc(lpXPDV->hScanBuf, lpXPDV->dwScanBufSize,
			GMEM_MOVEABLE | GMEM_ZEROINIT);

	  // if realloc fails, call ABORTDOC to clean up scan buf
	  if (!hTemp) {
	     MessageBox(NULL,"Memory not enough, quit some\napplication and try again.",
		"CopyPrinter Driver",
		MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL);
	     lpXPDV->func=100;
	     return SP_ERROR;
	  }
	  else
	  {
	     lpXPDV->hScanBuf  = hTemp;
	     lpXPDV->lpScanBuf = (char _huge *)GlobalLock(lpXPDV->hScanBuf);
	     lpXPDV->lpScanBuf += lpXPDV->dwTotalScanBytes;
	  }
       }

       lpXPDV->dwTotalScans +=Mod;
       for (Mod=0; Mod < wBytes; Mod++)
	  *lpXPDV->lpScanBuf++ = 0xff;
       lpXPDV->dwTotalScanBytes +=wBytes;
   }
   return SP_OK;
}

void utoa(DWORD dValue, LPSTR p)
{
   DWORD dtmp=0xf0000000;
   int i;

   for (i=7; i>=0; i--) {
      p[7-i]=(char)((dValue & dtmp)>>(4*i));
      if (p[7-i]<10)
	 p[7-i] +='0';
      else
	 p[7-i] = (char)(p[7-i]-10+'A');
      dtmp=dtmp>>4;
   }
   p[8]=0;
}

short ReLoad(LPEXTPDEV lpXPDV)
{
   BYTE _huge *p;

   _llseek(lpXPDV->hDIBFile, 0, 0);

   if (lpXPDV->hScanBuf) {
      GlobalUnlock(lpXPDV->hScanBuf);
      GlobalFree(lpXPDV->hScanBuf);
      if (!(lpXPDV->hScanBuf = GlobalAlloc(GPTR,lpXPDV->dwTotalCmp)))
	     return SP_ERROR;
      lpXPDV->lpScanBuf = (BYTE _huge *)GlobalLock(lpXPDV->hScanBuf);
   }

   p=(BYTE _huge *)lpXPDV->lpScanBuf;

   for (; QueryAbort(lpXPDV->hAppDC,0); p+=0x8000)
      if (_lread(lpXPDV->hDIBFile, p, 0x8000) < 0x8000)
	 break;

   _lclose(lpXPDV->hDIBFile);

   lpXPDV->hDIBFile = OpenFile((LPSTR)lpXPDV->szDIBFile,
			    (LPOFSTRUCT)&lpXPDV->of,
			    OF_DELETE);
   return SP_OK;
}

short WriteTmpFile(LPEXTPDEV lpXPDV)
{
   WORD i, j, wWidthBytes;
   BYTE ch,ch1;
   BYTE _huge *p;
   BYTE far *dwLine;
   WORD newWidth,lenCmp;
   DWORD dwBytes;

   if (Alloc(lpXPDV)!=SP_OK)

	return SP_ERROR;

   if (lpXPDV->func<105 || (lpXPDV->iPageNum%2)) {

     if ((lpXPDV->hDIBFile = OpenFile(lpXPDV->szDIBFile,
				    (LPOFSTRUCT)&lpXPDV->of,
				    OF_CREATE | OF_WRITE | OF_READ)) < 0)
       return SP_ERROR;

   }

   wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);

   p=(BYTE _huge *)(lpXPDV->lpScanBuf)-lpXPDV->dwTotalScanBytes;

   newWidth=(WORD)(lpXPDV->dwTotalScans/8);

   dwLine=(BYTE far *)lpXPDV->lpTmpBuf;

   for (i=0; i<wWidthBytes*8; i++) {
      ch1=(BYTE)(((BYTE)0x80)>>(i & 7));
      dwBytes=(DWORD)i>>3;
      for (j=0; j<newWidth; j++)
	  dwLine[j]=0;
      for (j=0; j<(WORD)lpXPDV->dwTotalScans; j++) {
	  ch=*(p+dwBytes);
	  if (!(ch & ch1))
	      dwLine[j>>3] |= (((BYTE)0x80)>>(j & 7));
	  dwBytes +=wWidthBytes;
      }

      lenCmp = cmp(lpXPDV,newWidth);

      _lwrite(lpXPDV->hDIBFile, dwLine+LINEBYTES, lenCmp);

      lpXPDV->dwTotalCmp +=lenCmp;
   }

   lpXPDV->dwTotalScans=wWidthBytes*8;

   return SP_OK;

}

void ErrorExit(LPEXTPDEV lpXPDV)
{
    if (lpXPDV->hScanBuf) {
	GlobalUnlock(lpXPDV->hScanBuf);
	GlobalFree(lpXPDV->hScanBuf);
	lpXPDV->hScanBuf = NULL;
    }
    if (lpXPDV->hTmpBuf) {
	GlobalUnlock(lpXPDV->hTmpBuf);
	GlobalFree(lpXPDV->hTmpBuf);
	lpXPDV->hTmpBuf = NULL;
    }
}

#ifndef NOCONTROL
short WINAPI Control(lpdv, function, lpInData, lpOutData)
LPDV    lpdv;
WORD    function;
LPSTR   lpInData;
LPSTR   lpOutData;
{
   LPEXTPDEV lpXPDV;
   short sRet,nRet;
   static DWORD dwTotalScans;
   static DWORD dwTotalScanBytes;

   // get pointer to our private data stored in UNIDRV's PDEVICE
   lpXPDV = ((LPEXTPDEV)lpdv->lpMd);

   switch (function)
   {
      case SETPRINTERDC:
	 // save app's DC for QueryAbort() calls
	 if (lpXPDV)
	    lpXPDV->hAppDC = *(HANDLE FAR *)lpInData;
	 break;

      case NEXTBAND:
      {
	 if (lpXPDV->func==100)
	     return SP_USERABORT;

	 // call UNIDRV.DLL's NEXTBAND to see if we're at end of page
	 sRet = UniControl(lpdv, function, lpInData, lpOutData);

	 // check for end of page (ie, empty rectangle) or failure
	 if ((!IsRectEmpty((LPRECT)lpOutData)) || (sRet <= 0))
	    return sRet;

	 // increment page number
	 lpXPDV->iPageNum++;

	 if (lpXPDV->func==103)
	    lpXPDV->lpScanBuf -= lpXPDV->dwTotalCmp;

	 if (lpXPDV->func==104) {

⌨️ 快捷键说明

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