📄 minidlg.c
字号:
/****************************************************************************
* *
* 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 + -