#include "dviout.h"
#include <commctrl.h>  // Common Controls を使用する
#include <stdio.h>
#include <io.h>
#include <math.h>
#include "option.h"
#include "err.h"

static BOOL GetPrinterDC( PRINTDLG* pPD );
static BOOL IsSupportedRaster( PRINTDLG* pPD );
static BOOL DefineDocument( PRINTDLG* pPD, BYTE* pDib );
static BOOL PreparePrinter( PRINTDLG* pPD );
BOOL CALLBACK AbortProc( HDC hdc, int nCode );
BOOL CALLBACK PrintHookProc( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK AbortPrintJob( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam );
void GetBoundingBox(BUFFER*, int, int, int, RECT *);

/* wmain.c */
HFONT SetFont( float, HWND, const char*, BOOL );
DWORD GetFontSize( int pt, const char* fontname, BOOL twobytes );
void SetMargin(HWND);

/* inter.c */
int GetPrintPage(char *, int, int, int *);

#define	CUT_SPACE	1

#define NORMALMODE		 0
#define ODDMODE			 1
#define EVENMODE		 2
#define SIDEBYSIDEMODE	 3
#define TOPLEFTBLANKMODE 4
#define RIGHTLEFTMODE	 5
#define TOPRIGHTBLANKMODE 6
#define	PAGINGMODE		 7

#define REVERSEMODE		 8
#define PAUSEMODE		16
#define UNITEMODE		32
#define ADJORIGMODE		64
#define	USEDVIPRT		0x1000
#define	OPTDVIPRT		0x2000

HBITMAP	hBitmap;
HDC		hMemDC;
BOOL	f_prtlarge;
BOOL	g_bPrintingByDVIPRT;
extern OPENFILENAME g_OpenFileName;
extern char		   g_szFileName[MAX_PATH]; // 開きたいﾌｧｲﾙ名
extern char		   *papersize_str[];
extern char		   *para_paper[];
extern int		   trans_papersize[];

extern int			LeftMargine;
extern int			TopMargine;
extern int			RightMargine;
extern int			BottomMargine;
extern int			PH;
extern int			PW;
extern SCALED_PT	OX;
extern SCALED_PT	OY;
extern int			f_GIF;
extern BOOL			f_area;
extern BOOL			f_rawfile;
extern BOOL			f_lbp_prt;
extern int			bmp_pt;

extern int			f_b_bcolor;
static BOOL bPrint;
static HWND hCancelDlg;

static int s_PPage;
static int s_mode; // the mode which defines a way of printing
static int print_dpi;  // dpi of the printer
static int copies;	// number of copies
static int new_enlarge;	 // change size for printing  x new_enlarge/1000
static int new_dist;  // change size for printing  x new_enlarge/1000

char *exec_dviprt;
static int f_exec_dviprt;
static char dviprtx[512];
static int op_w;
static int op_h;
static int op_y;
static int op_done;
static int f_lpt;
static int f_psupply;
static int paper_spl;
static int paper_mspl;
static int col_count;
static int dev_w;
static int dev_h;
static PRINTDLG pd;

static char *page_macro;
static int from_page, to_page;

int VERdvipdfmx(void)
{
	char *msg, *pt;
	static int ver_no;

	if(!ver_no){
		ver_no = -1;
		msg = GetCommandResult("dvipdfmx", 1);
		if(msg){
			pt = strstr(msg, "dvipdfmx");
			if(pt){
				while(*pt >= ' ' && (*pt <= '0' || *pt > '9'))
					pt++;
				ver_no = atoi(pt);
			}
			Free(msg);
		}
	}
	return ver_no;
}

void ClearhBitmap(void)
{
	if( hMemDC ) {
		DeleteDC( hMemDC );
		DeleteObject( hBitmap );
		hMemDC = NULL;
		hBitmap = NULL;
	}
}

static int GetPDpi(void)
{
	char tmp[] = "para0";
	int c_mode, p_mode;

	c_mode = SetParaSection(-1);
	p_mode = RestoreIntPara("pmode", c_mode);
	if(c_mode != p_mode){
		tmp[4] = p_mode + '0';
		return RestoreInt(tmp, "dpi", GetXDpi());
	}
	return GetXDpi();
}

static int Guessysize( int tmp, int reduce, int twotoone )
{
	int	tmp_org = tmp;

	if(tmp >= SIZE_A3 && tmp <= SIZE_A5){
		if(reduce < 908 && reduce > 822)
			tmp -= (SIZE_A4 - SIZE_B5);
		else if(reduce < 742 && reduce > 672)
			tmp++;
	}else if(tmp >= SIZE_B3 && tmp <= SIZE_B5){
		if(reduce < 856 && reduce > 776)
			tmp += (SIZE_A4 - SIZE_B4);
		if(reduce < 742 && reduce > 672)
			tmp++;
	}
	if(twotoone)
		tmp += (tmp != tmp_org || tmp == SIZE_A4 || tmp == SIZE_A5
			|| tmp == SIZE_B4 || tmp == SIZE_B5)?0xff:0x200;
	else if(tmp != tmp_org && (tmp == SIZE_B3 || tmp == SIZE_PCARD))
		tmp = tmp_org;
	return tmp;
}

static BOOL OutPara(FILE *fp, char *s)
{
	char *pt, *t;

	for(pt = common_work; *pt; pt++){
		if(*pt <= ' ')
			continue;
		if(*pt == '-'){
			pt++;
			for(t = s; *t; ){
				if(*pt++ != *t++)
					goto skp;
				if(!*pt)
					return FALSE;
			}
			if(*pt == '='){
				while(*++pt > ' ')
					putc(*pt, fp);
				return TRUE;
			}
		}
skp:	while(*pt > ' ')
			pt++;
	}
	return FALSE;
}

static void execdviprt( PRINTDLG* pPD )
{
#define	MAX_ARGC	256
	char *tdir0, *tdir, *argv[MAX_ARGC], tmpbuf[256];
	FILE *fp;
	int tmp, tmp1, ch, topage, frompage, f_XY;
#ifdef	RAWOUT
	int f_raw;
	int OrigPage;
	int old_mode;
	int old_xdpi, old_ydpi;
	int old_ox, old_oy;
	int f_blank;
	char *old_para;
#endif
	int f_cwin = 0;
	double ff;

#	define	TMP_PAGE	(common_work+0x400)
#	define	TMP_DVI		(common_work+0x800)
#	define	TMP_PATH	(common_work+0xc00)

	if( (topage = pPD->nToPage) < (frompage = pPD->nFromPage) )
		goto exec_dviprt_end;
	common_work[0] = *TMP_PAGE
#ifdef	RAWOUT
	= f_blank
#endif
	= 0;

#ifdef	RAWOUT
	f_raw = (*dviprtx=='`')?TRUE:FALSE;

	if(f_raw){
		old_para = MareaPara("GIF e varf y", 1);

		old_xdpi = GetXDpi();
		old_ydpi = GetYDpi();
		old_ox = OX;
		old_oy = OY;
		old_mode = SetParaSection(-1);
		OrigPage = GetCurrentPage();
		strcpy(common_work, "-o=^$");
		f_lbp_prt = (tolower(dviprtx[1]) == 'l' || tolower(dviprtx[1]) == 'm')?
			TRUE:FALSE;
	}else
#endif
	{
		if(GetParaFlag("half"))				/* magnification */
			strcpy(common_work, " -half");
		else{
			if((tmp = GetParaInt("mag")) >= 0)
			sprintf(common_work, " -mag=%d", tmp);
		}
		Free0(page_macro);
		page_macro = NULL;
	}
	if(copies > 1)							/* copy */
		sprintf(common_work + strlen(common_work),
			" -lc=%d", copies);
#ifdef	RAWOUT
	else if(f_raw)
		strcat(common_work, " -lc=1");
#endif

	if(s_mode & PAUSEMODE)					/* pause */
		strcat(common_work, " -Z+");
#ifdef	RAWOUT
	else if(f_raw)
		strcat(common_work, " -Z-");
#endif
											/* OX  & OY */
	ff = (s_mode & ADJORIGMODE)?2.54*((double)new_enlarge/1000-1):0;
	if(OX || (s_mode & ADJORIGMODE)){
		sprintf(common_work + strlen(common_work),
			" -OX=%.2fcm", (double)OX/0x10000/72.27*2.54 + ff ); /* SP -> cm */
	}
	if(OY || (s_mode & ADJORIGMODE)){
		sprintf(common_work + strlen(common_work),
			" -OY=%.2fcm", (double)OY/0x10000/72.27*2.54 + ff ); /* SP -> cm */
	}
											/* varf, e */
	tmp = GetParaInt("e");
	if(new_enlarge != 1000){
		strcat(common_work, " -varf+");
		if(tmp)
			new_enlarge = tmp*new_enlarge/1000;
		sprintf(common_work + strlen(common_work),
			" -e=%d", new_enlarge);
	}else{
		if(GetParaFlag("varf"))
			strcat(common_work, " -varf+");
		if(tmp != 0 && tmp != 1000)
			sprintf(common_work + strlen(common_work),
				" -e=%d", tmp);
	}

											/* y=paper size */
	tmp = (op_done == 1)?'P':'L';
	ch = op_y & 0xff;
	if(   !(ch >= SIZE_A3 && ch <= SIZE_A5)
	   && !(ch >= SIZE_B4 && ch <= SIZE_B5)
	   &&  ch != SIZE_USR){
		char *tmp_para;

		if( ch != SIZE_PCARD || ((op_y & 0x300) && (!f_raw || f_lbp_prt)) ){
			tmp_para = MareaPara("y", 1);
			sprintf(tmp_buf, "%s%c", para_paper[ch], tmp);
			SetParaString("y", tmp_buf);
			GetPaperSize100(&op_w, &op_h);
			MareaPara(tmp_para, -1);
			op_y = (op_y & ~0xff)|SIZE_USR;
		}
	}
	if((op_y & 0x300)
#ifdef	RAWOUT
	&& (!f_raw || f_lbp_prt)
#endif
	){							/* FukuroToji */
		sprintf(common_work + strlen(common_work),
			" -nf=%.2fcm",((double)new_dist)/100); 

								/* define a page size */
		if(tmp == 'P' || (op_y & 0x200) || new_dist == 0){
			if((op_y & 0xff) != SIZE_USR)
				sprintf(common_work + strlen(common_work),
					" -y=%s%c", para_paper[(op_y&0xff) -1], tmp);
			else
				sprintf(common_work + strlen(common_work),
					" -y=F%.2fcm:%.2fcm%c", 
					((double)op_w)/100, ((double)op_h)/100, tmp);
		}
		else if((op_y & 0xff) == SIZE_A5)
			strcat(common_work, " -y=F10.5cm:14.85cmP");
		else if((op_y & 0xff) == SIZE_B5)
			strcat(common_work, " -y=F12.85cm:18.2cmP");
		else
			sprintf(common_work + strlen(common_work),
				" -y=%sP", para_paper[op_y&0xff]);

								/* define a youshi size */
		if((op_y & 0xff) != SIZE_USR)
			sprintf(common_work + strlen(common_work),
				"/%s%c", para_paper[(op_y&0xff) -1], tmp);
		else
			sprintf(common_work + strlen(common_work),
				"/F%.2fcm:%.2fcm%c", ((double)op_w)/100, ((double)op_h)/100,
				tmp);
	}else{
		if((op_y & 0xff) != SIZE_USR)
			sprintf(common_work + strlen(common_work),
				" -y=%s%c", para_paper[(op_y&0xff)-1], tmp);
		else
			sprintf(common_work + strlen(common_work),
				" -y=F%.2fcm:%.2fcm%c", ((double)op_w)/100, ((double)op_h)/100,
				tmp);
	}
	if(f_psupply >= 0)
		sprintf(common_work + strlen(common_work), "%d", f_psupply);

	if(page_macro)
		goto page_range;
	switch(s_mode & PAGINGMODE){
		case EVENMODE:
			strcat(common_work, 
				(s_mode & REVERSEMODE)?" -o=re":" -o=e");
			break;

		case ODDMODE:
			strcat(common_work, 
				(s_mode & REVERSEMODE)?" -o=ro":" -o=o");
			break;

		case SIDEBYSIDEMODE:
#ifdef	RAWOUT
			if(s_mode & REVERSEMODE)
#endif
			{
				if(!((topage - frompage) & 1) )			/* odd pages */
					sprintf(TMP_PAGE + strlen(TMP_PAGE), "%d . ", topage--);
				strcat(TMP_PAGE, "M;y-=2,z-=1;y-1,y ");	/* Macro */
			}
#ifdef	RAWOUT
			else
				f_blank = !((topage - frompage) & 1);
#endif
			break;

		case RIGHTLEFTMODE:
			if(s_mode & REVERSEMODE){
				if(!((topage - frompage) & 1))		/* odd pages */
					sprintf(TMP_PAGE, ". ");
				strcat(common_work, " -o=r");
			}else{
				strcat(TMP_PAGE, "M;x+=2,z-=1;x+1,x ");		/* Macro */
#ifdef	RAWOUT
				f_blank = !((topage - frompage) & 1);
#endif
			}
			break;

		case TOPRIGHTBLANKMODE:
			if(s_mode & REVERSEMODE){
				if((topage - frompage) & 1)		/* even pages */
					sprintf(TMP_PAGE, ". ");
				strcat(common_work, " -o=r");
			}else{
				sprintf(TMP_PAGE + strlen(TMP_PAGE), "%d . ", frompage++);
				strcat(TMP_PAGE, "M;x+=2,z-=1;x+1,x ");		/* Macro */
#ifdef	RAWOUT
				f_blank = !((topage - frompage) & 1);
#endif
			}
			break;

		case TOPLEFTBLANKMODE:
			if(s_mode & REVERSEMODE){
				if((topage - frompage) & 1)		/* even pages */
					sprintf(TMP_PAGE + strlen(TMP_PAGE), "%d . ", topage--);
				strcat(TMP_PAGE, "M;y-=2,z-=1;y-1,y ");	/* Macro */
			}else
				strcat(TMP_PAGE, ". ");
#ifdef	RAWOUT
			f_blank = (topage - frompage) & 1;
#endif
			break;

		default:
			if(s_mode & REVERSEMODE)
				strcat(common_work, " -o=r");
			break;
	}
page_range:
	sprintf(TMP_PAGE+strlen(TMP_PAGE), "%d-%d", frompage, topage);
	if(col_count > 1
#ifdef	RAWOUT
		&& f_blank
#endif
	)
		strcat(TMP_PAGE, " .");
#ifdef	RAWOUT
	if(f_raw){							/* raw mode WinAPI print */
# if 0
		if(tolower(dviprtx[1]) == 'l' && strstr(dviprtx, "D600")){
			MessageBox( NULL, "LIPS IV is not supported.", NULL, MB_OK );
			f_lbp_prt = FALSE;
			goto exec_dviprt_end;
		}
# endif
		SetParaSection( RestoreIntPara("pmode", old_mode) );
		if(SetParaSection(-1) != old_mode)
			RestoreRegistry();
		if(dviprtx[1] <= 'Z' && dviprtx[1] >= 'A'){
			ReSetDpi();
		}else if(tolower(dviprtx[1]) == 'm' || tolower(dviprtx[1]) == 'l'){
			char *pt;

			tmp = 300;
			pt= dviprtx+1;
			if(*(pt+1) == 'D' || (pt = strstr(dviprtx, ";D")) != NULL)
				tmp = atoi(pt + 2);
			if(GetXDpi() != tmp){
				wsprintf(tmpbuf, 
				"Printer driver      : %ddpi\n"
				"Current resolution: %ddpi\n"
				"Use driver resolution to print?",
				tmp, GetPDpi());
				switch(MessageBox( g_winData.hMainWnd, tmpbuf, 
					"Warning", MB_YESNOCANCEL|MB_ICONEXCLAMATION )){
					case IDCANCEL:
						goto quit_end;
					case IDOK:
						RestoreIntPara("dpi", tmp);
					case IDNO:
					default:
						break;
				}
			}
		}
		SetParaStringDirect("p", dviprtx+1);
		tdir = dup_string(common_work);
		SetPara(tdir, SET_OPTION);
		Free0(tdir);
		tdir = tdir0 = dup_string(TMP_PAGE);
		argv[0] = argv[1] = "";			/* command & dvi_file */
		for(tmp = 2; tmp < 7; tmp++){
			while(*tdir <= ' '){
				if(!*tdir)
					goto arg_out;
				else
					*tdir++ = 0;
			}
			argv[tmp] = tdir;
			while(*tdir > ' ')
				tdir++;
		}
arg_out:
		tmp1 = tmp;
		while(col_count > 1 && tmp < (MAX_ARGC - 7)){
			for(ch = 2; ch < tmp1; )
				argv[tmp++] = argv[ch++];
			col_count--;
		}
		if(page_macro){
			argv[tmp] = argv[tmp-1];
			argv[tmp-1] = page_macro;
			if(*page_macro == '@')
				tmp++;
		}
		argv[tmp] = NULL;
		if(f_GIF >= 2)
			f_GIF = 2;
		PrintRaw(tmp, argv);
		Free0(tdir0);
quit_end:
		if(old_mode != SetParaSection(-1)){
			SetParaSection(old_mode);
			RestoreRegistry();
		}

		SetParaString("p", "^$");
		SetParaInt("dpi", old_xdpi);
		if(old_xdpi != old_ydpi)
			SetParaInt("dpi", old_ydpi);
		OX = old_ox;
		OY = old_oy;
		ReSetMetric();
		MareaPara(old_para, -1);
		ChgPage(OrigPage);
		ExpandPage();
		goto exec_dviprt_end;
	}
#endif
	if(	!SetPath(TMP_PATH, "^?") ){
		strcpy(TMP_PATH, GetOutPath("exe"));
		*(TMP_PATH-11 + strlen(TMP_PATH)) = 0;
	}
	tdir = TMP_PATH + strlen(TMP_PATH);

	strcpy(tdir, "\\dvitmp.par");
	if((fp = fopenf(TMP_PATH, "wt")) == NULL)
		goto exec_dviprt_end;
	fputs(common_work, fp);
	putc(' ', fp);
	fclose(fp);
	tdir += 8;

	strcpy(tdir, "bat");
	if((fp = fopenf(TMP_PATH, "wt")) == NULL)
		goto exec_dviprt_end;
	strcpy(tdir, "$$$");

	for(tmp = f_XY = 0; (ch = dviprtx[tmp++]) != 0; ){
		if( (f_XY == 1 && ch == '}') || (f_XY == 2 && ch == '{') ){
			f_XY = 0;
			continue;
		}
		if(ch == '^'){
hat:		ch = dviprtx[tmp++];
			if(isalpha(ch)){
				switch(ch){
					case 'f':
						strcpy(tdir, "par");
						fputs(TMP_PATH, fp);
						break;

					case 't':
						strcpy(tdir, "$$$");
						fputs(TMP_PATH, fp);
						break;

					case 'p':
						fputs(TMP_PAGE, fp);
						break;

					case 'q':
						fputs(current_name, fp);
						break;

					case 'D':
					case 'd':
						strcpy(common_work + 0x1000, current_name);
						common_work[(0x1000-4)+strlen(common_work+0x1000)] = 0;
						tmp1 = (ch=='D')?GetNamePos(common_work+0x1000):0;
						fputs(common_work+0x1000+tmp1, fp);
						break;

					case 'P':
						fprintf(fp, "dviprt.exe %s %s", current_name, TMP_PAGE);
						break;

					case 'x':
						strcpy(common_work + 0x1000, GetOutPath("exe"));
						common_work[0x1000-11 + strlen(common_work + 0x1000)]
							= 0;
						fputs(common_work + 0x1000, fp);
						break;

					case 'W':	/* Set Paper size, Copy, Even/Odd/Reverse/OX/OY */
						if(op_done != 1)
							fprintf(fp, "-t landscape -T %.2fmm,%.2fmm",
								SP_TO_MM(PH), SP_TO_MM(PW));
						else
							fprintf(fp, "-T %.2fmm,%.2fmm", SP_TO_MM(PW), SP_TO_MM(PH));
						if(OX||OY)
							fprintf(fp, " -O %.2fmm,%.2fmm", SP_TO_MM(OX), SP_TO_MM(OY));
						if(s_mode & REVERSEMODE)
							fputs(" -r", fp);
						switch(s_mode & PAGINGMODE){
							case ODDMODE:
								fputs(" -A", fp);
								break;
							case EVENMODE:
								fputs(" -B", fp);
								break;
						}
						if(copies > 1)							/* copy */
							fprintf(fp, " -c %d", copies);
						break;

					case 'w':		/* Set Paper size, OX, OY for dvipdfm */
						common_work[0x1000] = 0;
						switch(op_y & 0xff){
							case SIZE_A3:
							case SIZE_A4:
							case SIZE_A5:
							case SIZE_A6:
								sprintf(common_work+0x1000, "-p a%c", 
									'3'+ (op_y&0xff) - SIZE_A3);
								break;
							case SIZE_B3:
							case SIZE_B4:
							case SIZE_B5:
							case SIZE_B6:
								sprintf(common_work+0x1000, "-p b%c", 
									'3'+ (op_y&0xff) - SIZE_B3);
								break;
							case SIZE_LETTER:
								strcpy(common_work+0x1000, "-p letter");
								break;
							case SIZE_LEGAL:
								strcpy(common_work+0x1000, "-p legal");
								break;
							default:
								if(strstr(dviprtx, "dvipdfmx") ||
								  (strstr(dviprtx, "dvipdfm^X{x}") && f_rawfile) ||
								  (strstr(dviprtx, "dvipdfm^X}x{") && !f_rawfile) ||
								  (strstr(dviprtx, "dvipdfm^Y{x}") && (s_mode & REVERSEMODE)) ||
								  (strstr(dviprtx, "dvipdfm^Y}x{") && !(s_mode & REVERSEMODE)) ){
									if(VERdvipdfmx()>=20040204){
										if(op_done != 1)
											sprintf(common_work+0x1000,
											"-p %.2fmm,%.2fmm", SP_TO_MM(PH), SP_TO_MM(PW));
										else
											sprintf(common_work+0x1000,
											"-p %.2fmm,%.2fmm", SP_TO_MM(PW), SP_TO_MM(PH));
									}
								}
						}
						if(common_work[0x1000]){
							fputs(common_work + 0x1000, fp);
							if(op_done != 1)
								fputs(" -l", fp);
						}
						if(OX)
							fprintf(fp, " -x %.3fin", (double)OX/0x10000/72.27 + 1);
						if(OY)
							fprintf(fp, " -y %.3fin", (double)OY/0x10000/72.27 + 1);
						break;

					case 'S':
						putc('^', fp);
						break;

					case 's':
						putc(' ', fp);
						break;

								/* special options */
					case 'A':
						fprintf(fp, "%d", TransPage(pPD->nFromPage));
						break;

					case 'B':
						fprintf(fp, "%d", TransPage(pPD->nToPage));
						break;

					case 'a':
						fprintf(fp, "%d", pPD->nFromPage);
						break;

					case 'b':
						fprintf(fp, "%d", pPD->nToPage);
						break;

					case 'e':
						fprintf(fp, "%d", new_enlarge);
						break;

					case 'm':
						fprintf(fp, "%d", s_mode & PAGINGMODE);
						break;

					case 'n':
						OutPara(fp, "nf");
						break;

					case 'c':
						if(!OutPara(fp, "lc"))
							putc('1', fp);
						break;

					case 'y':
						OutPara(fp, "y");
						break;

					case 'h':
						if(!OutPara(fp, "OX"))
							fputs("0cm", fp);
						break;

					case 'v':
						if(!OutPara(fp, "OY"))
							fputs("0cm", fp);
						break;

					case 'o':
						OutPara(fp, "o");
						break;

					case 'X':
					case 'Y':
						if(dviprtx[tmp] == '{')
						   f_XY = 1;
						else if(dviprtx[tmp] == '}')
						   f_XY = 2;
						else
							continue;
						if(  (ch == 'X' && f_rawfile)
						  || (ch == 'Y' && (s_mode & REVERSEMODE))){
							if(f_XY == 1){
								tmp++;
							}else{
								while(dviprtx[tmp] && dviprtx[tmp++] != '{');
								f_XY = 0;
							}
						}else{
							if(f_XY == 2)
								tmp++;
							else{
								while(dviprtx[tmp] && dviprtx[tmp++] != '}');
								f_XY = 0;
							}
						}
						break;

					case 'z':
						f_cwin = 2;
					case 'Z':
						goto close;
				}
				continue;
			}
			if(!ch)
				break;
			putc(' ', fp);
			if(ch == '^')
				goto hat;
		}
		putc((ch == ';')?'\n':ch, fp);
	}
close:
	fclose(fp);
	strcpy(tdir, "bat");
	argv[0] = (f_osversion<0)?"command.com":"cmd.exe";
	argv[1] = "/c";
	argv[2] = TMP_PATH;
	argv[3] = NULL;
	if(	   (fp = fopenf(TMP_PATH, "rt")) != NULL
		&& fgets(common_work, 0x400, fp) != NULL
		&& feof(fp)){
		fclose(fp);
		for(tdir = common_work; *tdir > ' '; tdir++);
		if(!strchr(common_work, '\n')
		  && tdir > common_work + 4
		  && *--tdir=='e' && *--tdir=='x' && *--tdir=='e' && *--tdir=='.'){
			argv[0] = common_work;
			argv[1] = NULL;
		}
	}
	if(argv[1] && strstr(TMP_PATH, "　")){
		*(argv[2] = TMP_PATH-1) = '"';
		strcat(TMP_PATH, "\"");
	}
	WinMinExecute(argv, 1|f_cwin, TRUE);
exec_dviprt_end:
	if( IS_MPAGE && IS_16PAGE )
		SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_16PAGE, 0 );
	else if( IS_MPAGE )
		SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_CROSS, 0 );
	else return;
}

void PrintBmp( BYTE* pDib )
{
	/*	以下にはWindowsにおいて印刷処理の流れを示す 
		1: プリンタデバイスコンテキストの取得。
		   プリンタデバイスコンテキストはウィンドウマネージャが保持する
		   ものではない。従って、GetDCなどで得ることはできない。
		   CreateDC で作成するか（複雑）PrintDlgでダイアログを
		   開いて取得する（簡単）。
		   もしドライバのライブラリモジュールがロードされていなければ
		   ロードされ，初期化が行なわれる。
		2: 印刷準備
		   アプリケーションは印刷準備を行なわなければならない。
		   そのために、まず使用したいものが、選択されたプリンタで
		   サポートされているかを調べる。
		   その後、印刷開始の前に印刷の強制終了に対応する
		   ダイアログを作成する
		3: 印刷処理
		   StartDocを呼び出すと、印刷ジョブが開始する。
		   印刷ジョブが始まったら、StartPageとEndPage函数の
		   呼び出しの間に、GDI函数を呼び出すことによって
		   各ページの内容を定義することができる。
		   最後のページを印刷し終わったら、EndDocを呼び出し、
		   印刷ジョブを終了する。

		注: Windowsアプリの処理において、印刷とはすなわち
			GDIモジュールがプリンタ出力をディスクのファイルに
			保存するということと同値である。
			Windowsは、Windows Meta File(WMF)形式のファイルをサポートする。
			このファイルは実際にはGDIコールの集合体であり、
			プリンタスプールファイルはWMFファイルである。
		注: プリントマネージャはWindowsのスプール機構である。
			これを無視することもでき、無視することがよい影響を生む
			こともある。
	*/
	double	tx, ty, px, py;
	RECT rc;

retry: 
	print_dpi = paper_spl = paper_mspl = 0;
	f_psupply = -1;
										// プリンタデバイスコンテキストを取得
	if( GetPrinterDC( &pd ) == FALSE ) return; 
	if( s_mode & USEDVIPRT ){
		if(col_count){
			col_count = copies;
			copies = 1;
		}
		do{
			execdviprt( &pd );
		}while(--col_count > 0);
		goto quit;
	}
	if( IsSupportedRaster( &pd ) == FALSE )	// ラスタサポートをチェック
		goto quit;
//	Check paper size and orientation
	tx = (double)GetTextXSize()/GetXDpi()*2.54;
	ty = (double)GetTextYSize()/GetYDpi()*2.54;
	if(new_enlarge != 1000){
		tx = tx*new_enlarge/1000;
		ty = ty*new_enlarge/1000;
	}
	if( (s_mode & PAGINGMODE) >= SIDEBYSIDEMODE
	 &&	(s_mode & PAGINGMODE) <= TOPRIGHTBLANKMODE )
		tx += (double)new_dist/100;
	px = (double)(dev_w = GetDeviceCaps( pd.hDC, PHYSICALWIDTH ))
			/GetDeviceCaps( pd.hDC, LOGPIXELSX )*2.54;
	py = (double)(dev_h = GetDeviceCaps( pd.hDC, PHYSICALHEIGHT ))
			/GetDeviceCaps( pd.hDC, LOGPIXELSY )*2.54;
	if(px/tx > 1.05 || px/tx < 0.95 || py/ty > 1.05 || py/ty < 0.95)
	{
		sprintf((char *)common_work, 
			"Desired paper size for text: %.2f x %.2f cm\n"
			"Supposed by printer driver : %.2f x %.2f cm\n"
			"Retry the print setting?",
			tx, ty, px, py);
		if( MessageBox( g_winData.hMainWnd, (char *)common_work, 
			"Warning", MB_YESNO|MB_ICONEXCLAMATION ) == IDYES ){
ret0:		GetClientRect(g_winData.hMainWnd, &rc);
			InvalidateRect(g_winData.hMainWnd, &rc, TRUE);
			goto retry;
		}
	}
// Check resolution
	print_dpi = GetDeviceCaps( pd.hDC, LOGPIXELSX );
	if(print_dpi && print_dpi != GetPDpi()){
		wsprintf((char *)common_work, 
			"Printer resolution: %ddpi\n"
			"Current resolution: %ddpi\n"
			"Use Printer resolution to print?",
			print_dpi, GetPDpi());
		switch(MessageBox( g_winData.hMainWnd, (char *)common_work, 
			"Warning", MB_YESNOCANCEL|MB_ICONEXCLAMATION )){
			case IDCANCEL:
				goto ret0;
			case IDNO:
				print_dpi=0;
			case IDOK:
			default:
				break;
		}
	}else
		print_dpi = 0;
	UpdateWindow( g_winData.dviwin.hWnd );
	f_dstop = 1;
	PreparePrinter( &pd );
	DefineDocument( &pd, pDib );
quit:
	Free0(page_macro);
	page_macro = NULL;
	return;
}

static BOOL GetPrinterDC( PRINTDLG* pPD )
{ /* CreateDC によるプリンタデバイスコンテキストの取得はプリンタ名等を
	 指定する必要があり、やっかいである。
	 ここでは、プリンタダイアログを使用してそれらを取得する。
	 これは自然な解決策だと思う。*/

	memset( (void*)pPD, 0, sizeof(PRINTDLG) );

	pPD->lStructSize = sizeof(PRINTDLG);// size of structure.
	pPD->hwndOwner	 = g_winData.hMainWnd;// a window that owns the dialog box.
	pPD->hDevMode	 = (HANDLE)NULL; // memory object that points DEVMODE
	pPD->hDevNames	 = (HANDLE)NULL; // memory object that points DEVNAMES
	pPD->hDC		 = (HDC)NULL;	 // device context.
	pPD->Flags		 = PD_RETURNDC | PD_USEDEVMODECOPIES | PD_COLLATE
					 | PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE
											// enable to hook print proc.
//					 | PD_DISABLEPRINTTOFILE
					 ;
	pPD->nFromPage	 = 1;			 // start page.
	pPD->nToPage	 = GetTotalPage(); // end page.
	pPD->nMinPage	 = 1;
	pPD->nMaxPage	 = GetTotalPage();
	pPD->nCopies	 = 1;
//	 pPD->hInstance	  = (HANDLE)NULL;
	pPD->hInstance	 = g_winData.hInstance;
	pPD->lCustData	 = 0L;
//	  pPD->lpfnPrintHook = (LPPRINTHOOKPROC)NULL;
	pPD->lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc;
	pPD->lpfnSetupHook = (LPSETUPHOOKPROC)NULL;
//	  pPD->lpPrintTemplateName = (LPSTR)NULL;
	pPD->lpPrintTemplateName = (LPSTR)MAKEINTRESOURCE(IDD_OPTPRT);
	pPD->lpSetupTemplateName = (LPSTR)NULL;
	pPD->hPrintTemplate = (HANDLE)NULL;
	pPD->hSetupTemplate = (HANDLE)NULL;

	return PrintDlg( pPD );
}

static BOOL IsSupportedRaster( PRINTDLG* pPD )
{
	if( !( GetDeviceCaps( pPD->hDC, RASTERCAPS ) & RC_BITBLT ) )
	{
		DeleteDC( pPD->hDC );
		MessageBox( g_winData.hMainWnd, "Printer cannot print bitmaps.", 
			"Device Error", MB_OK | MB_ICONEXCLAMATION );
		return FALSE;
	}
	else return TRUE;
}

static BOOL PreparePrinter( PRINTDLG* pPD )
{
	/* プリント中止プロシージャをWindowsに登録すると、Windowsは
	   この函数をジョブ全体のスプーリングが終了するまでの間、
	   ２秒おきに呼び出す。 */

	bPrint = TRUE; // プリント実行フラグをTRUE
	/* 中止用函数 AbortProc を登録 */
	SetAbortProc( pPD->hDC, AbortProc );
	/* ダイアログボックスを作成する */
	hCancelDlg = CreateDialog( g_winData.hInstance, 
								MAKEINTRESOURCE(IDD_PRINTABORTDIALOG),
							   g_winData.hMainWnd, (DLGPROC)AbortPrintJob );
	EnableWindow( g_winData.hMainWnd, FALSE );
	return TRUE;
}

BOOL CALLBACK AbortProc( HDC hdc, int nCode )
{
	/* この函数はWindowsシステムが２秒おきに呼び出す。
	   決して直接呼んではならない */
	MSG msg;
	
	/* メッセージキューからメッセージを取り出し、破棄する */
	while( PeekMessage( (LPMSG)&msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
	{
		if( !IsDialogMessage( hCancelDlg, (LPMSG)&msg ) )
		{ /* メッセージがダイアログに宛てられたものでなければ */
			/* キーボードアクセラレーションはさぼる(笑) */
			TranslateMessage( (LPMSG)&msg );
			DispatchMessage( (LPMSG)&msg );
		}
	}
	return bPrint;
}

LRESULT CALLBACK AbortPrintJob( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_INITDIALOG:
//			wsprintf( szPage, "%d page", s_PPage );
//			SetDlgItemText( hwndDlg, IDC_PRINTINGPAGE, szPage );
			return TRUE;
		
		case WM_COMMAND:
			if( MessageBox( hwndDlg, "I notice your request "
								"--- stop printing!\n"
								"May I really stop printing?", 
								"STOPPING REQUEST", MB_YESNO ) == IDYES )
			{
				bPrint = FALSE;
				return TRUE;
			}
			else
			{
				bPrint = TRUE;
				return TRUE;
			}
	}
	return FALSE;
}

int PrintKeepBMP(HDC hdc, HDC hdc2, BYTE *pBMP, int type, int f_and, 
	int xd_pos, int yd_pos, int wd, int hd,
	int xs_pos, int ys_pos, int ws, int hs, int y_org)
{
	BYTE *pBMPBits;
	int nError;

	pBMPBits = GetDibBitsAddress( pBMP );
	if(type == -4){
		type--;
		if(!ChangeColor( pBMP, (SetGamma(0)>0)?1:0 )){
			type--;
			goto skp;
		}
	}
rep:
	if( (	f_and == SRCCOPY
		|| (hdc2 != NULL && (ws <= MAX_FSIZE && hs <= MAX_FSIZE)) )
	  && wd >= ws - G_ROOM && wd <= ws + G_ROOM
	  && hd >= hs - G_ROOM && hd <= hs + G_ROOM ){
		if(f_and == SRCCOPY)
			nError = SetDIBitsToDevice(hdc,
				xd_pos, yd_pos, ws, hs, xs_pos, ys_pos, 0, y_org,
				(LPSTR)pBMPBits, (LPBITMAPINFO)pBMP, DIB_RGB_COLORS);
		else{
			nError = SetDIBitsToDevice( hdc2,
				0, 0, ws, hs, xs_pos, ys_pos, 0, y_org,
				(LPSTR)pBMPBits, (LPBITMAPINFO)pBMP, DIB_RGB_COLORS);
			  if(!nError)
				return 0;
			  nError = BitBlt(hdc, xd_pos, yd_pos, ws, hs, 
				hdc2, 0, 0, f_and);
			  goto skp0;
		}
	}else
		nError = StretchDIBits( hdc,
			xd_pos, yd_pos, wd, hd, xs_pos, ys_pos, ws, hs,
			(LPSTR)pBMPBits, (LPBITMAPINFO)pBMP, DIB_RGB_COLORS, f_and);
skp0:
	if(type-- == -5){
		ChangeColor( pBMP, -1 );
skp:	f_and = (f_and == SRCAND)?SRCPAINT:SRCAND;
		goto rep;
	}
	return nError;
}

static BOOL DefineDocument( PRINTDLG* pPD, BYTE* pDib )
{
	DOCINFO di;		// ドキュメントデータの構造体
	BYTE* pDibBits; // Dibのデータ
	int nError;		// エラーコード格納変数
	UINT cxDib, cyDib, OrigPage;
	int gamma;
	int org_bright;
	int step;
	int right_shift;
	int dist;
	int repeat;
	int left_page;
	int f_fukuro;
	int old_enlarge;
	int paper_width;
	int paper_height;
	int old_mode;
	int old_xdpi;
	int old_ydpi;
	int old_ox;
	int old_oy;
	int old_rpc;
	char old_y[0x20];
	BOOL old_resize;
	BOOL old_gfit;
	BOOL closed_job;
	POINT pt;
	BOOL result = TRUE;
	char szPage[32];
	char szJob[128];
	int count;
	BYTE *pBMP;
	int x_pos, y_pos, x_size, y_size, x_org, y_org, type, f_and;
	int x_cut1, x_cut2, y_cut1, y_cut2, x_cutsize, y_cutsize;
	int x_cut1o, y_cut2o;
	int	L_M, R_M, T_M, B_M, logw, logh, lm, tm;
	int ws, hs;
	int old_para;
	RECT bx;
	int reserve_2page, reserve_2page_mode;
	int s_PPage2, f_mode;
	
#define	PDEBUG	1
	strcpy(szJob, "DVIOUT");
	if((lm = strlen(current_name_pt)) < 120){
		sprintf(szJob + 6, "-%s", current_name_pt);
		if(!(strcmp(szJob + lm + 3, ".dvi")))
			szJob[lm+1] = 0;
	}
	memset( (void *)&di, 0, sizeof(DOCINFO));
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = szJob; // 印刷ジョブの名前
//	di.lpszOutput = (LPTSTR)NULL; 出力先ファイル。今はファイルにリダイレクトしない。

	/* 印刷ジョブを開始する */
#if	PDEBUG
	nError = StartDoc( pPD->hDC, &di );
	if( nError == SP_ERROR )
	{ /* 一般的なエラーだって。まいったなこりゃ */
		MessageBox( g_winData.hMainWnd, "an error on StartDoc.", NULL, MB_OK | MB_ICONSTOP );
		EnableWindow( g_winData.hMainWnd, TRUE );
		DestroyWindow( hCancelDlg );
		DeleteDC( pPD->hDC );
		return FALSE;
	}
#endif
	OrigPage = GetCurrentPage();
	org_bright = bright;
	gamma = SetGamma(0);
	f_fukuro = f_mode = 0;
		/* Wait other ExpandPage() in patch2 for at most 20 sec */
	if(!(s_mode & REVERSEMODE)){
		s_PPage = pPD->nFromPage;
		step = 1;
	}else{
		s_PPage = pPD->nToPage;
		step = -1;
	}
	switch(s_mode & PAGINGMODE){
		case EVENMODE:
			if(s_PPage & 1)
				s_PPage += step;
			step *= 2;
			break;
		case ODDMODE:
			if(!(s_PPage & 1))
				s_PPage += step;
			step *= 2;
			break;
		case SIDEBYSIDEMODE:
		case RIGHTLEFTMODE:
			f_fukuro = 1;
			if(step < 0 && ((pPD->nToPage - pPD->nFromPage)&1) ) // even pages
				s_PPage--;
			step *= 2;
			break;
		case TOPLEFTBLANKMODE:
		case TOPRIGHTBLANKMODE:
			f_fukuro = 1;
			if(step > 0 || !((pPD->nToPage - pPD->nFromPage)&1))  // odd pages
				s_PPage--;
			step *= 2;
			break;
		default:
			break;
	}
	if(page_macro){
		s_PPage = GetPrintPage(page_macro, pPD->nFromPage, pPD->nToPage, &f_mode);
		s_PPage2 = f_fukuro?GetPrintPage(NULL, pPD->nFromPage, pPD->nToPage, &f_mode):(-3);
	}
	closed_job = FALSE;
	old_enlarge = GetParaInt("e");
	old_resize = GetParaFlag("varf");
	old_gfit = GetParaFlag("gfit");
	if(GetParaString("y") != NULL)
		strncpy(old_y, GetParaString("y"), 0x20);
	else
		strcpy(old_y, "A4P");
	old_mode = SetParaSection(-1);
	old_ox = OX;
	old_oy = OY;
	old_rpc = f_rpcolor;
	SetParaSection( RestoreIntPara("pmode", old_mode) );
	paper_width = 0;
	old_para = -1;
	if(SetParaSection(-1) != old_mode){
		old_para = KeepPara(-1);
		RestoreRegistry();
		paper_width = 1;
	}
	if(print_dpi != 0){
		old_xdpi = GetXDpi();
		old_ydpi = GetYDpi();
		SetParaInt("dpi", print_dpi);
		paper_width = 1;
	}
	if(old_gfit)
		paper_width = 1;
	bright = 255;
	SetGamma(1000);
	SetParaFlag("gfit", FALSE);
#ifdef	DOUBLE_PAGE
	reserve_2page_mode = (f_2page&F_2PAGE) | (f_2page&F_2REV);
	if((reserve_2page = f_2page) != 0){
		f_2page = 0;
		Clear2Page();
		ClearKeepBMP();
		goto expp;
	}
#endif
	if(f_rpcolor == 6){
		f_rpcolor = 2;
		goto expp;
	}
	if(paper_width || (bmp_pt > 0 && f_rpcolor != 0 && !(f_rpcolor & 4)))
expp:	ExpandPage0();
	dist = (double)new_dist/254*GetXDpi() + 0.5;
	paper_height = GetTextYSize();
	paper_width = GetTextXSize();
	if(new_enlarge != 1000 && new_enlarge > 0){
		char tmp[32];
		sprintf(tmp, "%ddot/%ddpi", paper_width*new_enlarge/1000, GetXDpi());
		SetParaString((f_rotate)?"PH":"PW", tmp);
		sprintf(tmp, "%ddot/%ddpi", paper_height*new_enlarge/1000, GetYDpi());
		SetParaString((f_rotate)?"PW":"PH",tmp);
		SetParaFlag("varf",TRUE);
		if(s_mode & ADJORIGMODE){
			OX += ((double)new_enlarge/1000 - 1)*(0x10000*72.27);	/* SP */
			OY += ((double)new_enlarge/1000 - 1)*(0x10000*72.27);	/* SP */
		}
		if(old_enlarge)
			new_enlarge = new_enlarge*old_enlarge/1000;
		SetParaInt("e", new_enlarge);
	}else
		new_enlarge = 0;
	if(f_area){
		L_M = GetDeviceCaps(pPD->hDC, PHYSICALOFFSETX);
		T_M = GetDeviceCaps(pPD->hDC, PHYSICALOFFSETY);
		R_M = B_M = 0;
	}else{
		L_M = LeftMargine;
		R_M = RightMargine;
		T_M = TopMargine;
		B_M = BottomMargine;
	}
	ClearhBitmap();
	hBitmap = CreateCompatibleBitmap(pPD->hDC, MAX_FSIZE, MAX_FSIZE);
	hMemDC	= CreateCompatibleDC(pPD->hDC);
	SelectObject(hMemDC, hBitmap);
	if(!f_rpcolor){
		f_rpcolor = 5;
		ClearKeepBMP();
		ClearKeepBMP();
	}
	while(1)
	{
repeat_job:
		if(bPrint != TRUE)
			break;
		if(page_macro){
			if(!s_PPage || s_PPage == -2 || s_PPage2 == -2)
				break;
		}else if(s_PPage > pPD->nToPage
		  || (s_PPage + ((step > 0)?step:-step)) <= pPD->nFromPage)
			break;
		strcpy(szPage, "Print? : ");
		if(s_PPage >= pPD->nFromPage || (page_macro && s_PPage > 0))
			sprintf(szPage + strlen(szPage), "%d(%d) ", 
				s_PPage, TransPage(s_PPage));
		if(page_macro){
			if(s_PPage2 > 0){
				sprintf(szPage + strlen(szPage), "%d(%d) ", 
				s_PPage2, TransPage(s_PPage2));
			}
		}else if((step < -1 || step > 1) &&f_fukuro && s_PPage < pPD->nToPage)
			sprintf(szPage + strlen(szPage), "%d(%d) ", 
				s_PPage+1, TransPage(s_PPage+1));
		strcat(szPage, "page");
		if(!(s_mode & UNITEMODE) || f_mode)
		{			/* Pause before printing a sheet */
			if( ((s_mode & PAUSEMODE) || f_mode) && 
				MessageBox(g_winData.hMainWnd, szPage, "PAUSE", MB_OKCANCEL)
					== IDCANCEL )
				goto err;
			if(closed_job){
#if	PDEBUG
				nError = StartDoc( pPD->hDC, &di );
				if( nError == SP_ERROR ){
					MessageBox( g_winData.hMainWnd, "an error on StartDoc.", 
						NULL, MB_OK | MB_ICONSTOP );
					goto err;
				}
#endif
				closed_job = FALSE;
			}
		}
		SetDlgItemText( hCancelDlg, IDC_PRINTINGPAGE, szPage + 9 );
#if	PDEBUG
	   /* データ送信を開始する！ */
		nError = StartPage( pPD->hDC );
		if( nError <= 0 ) // StartPageは正常終了で"正の値を返す"
		{
			MessageBox( g_winData.hMainWnd, "an error on StartPage.", 
				NULL, MB_OK | MB_ICONSTOP );
			goto err;
		}
		/* あとは、ディスプレイに描くが如くGDIを呼び出す */
		SetMapMode( pPD->hDC, MM_TEXT );
		MoveToEx( pPD->hDC, 0, 0, &pt );
		SetStretchBltMode( pPD->hDC, COLORONCOLOR );  /* 総て描画し直し */
#endif
		repeat = 0;
		right_shift = ((s_mode & PAGINGMODE) == RIGHTLEFTMODE )?dist:0;
		left_page = s_PPage;
		while(1){
			if(page_macro){
				if(s_PPage <= 0)
					goto next;
			}else if(s_PPage < pPD->nFromPage || s_PPage > pPD->nToPage)
				goto next;
			logw = GetDeviceCaps(pPD->hDC, HORZRES) - right_shift;
			if(logw <= 0 ||
			  logw > dev_w - L_M - R_M)
				logw = dev_w - L_M - R_M;

			logh = GetDeviceCaps(pPD->hDC, VERTRES);
			if(logh <= 0 || logh > dev_h - T_M - B_M)
				logh = dev_h - T_M - B_M;
			if(logw <= 0 || logh <=0)
				goto next;
#if 0
			if(!old_rpc){			/* auto mode */
//			  if(IsAllTT())
				f_spsh = -1;
				ChgPage(s_PPage);
				ExpandPage0();		/* check \special{sh ..} */
				if(f_spsh){
					f_rpcolor = 2;
					InitTTOut(NULL, 0, 0, 1, 1);
				}else{
					if(f_rpcolor != 5){
						f_rpcolor = 5;
						ClearKeepBMP();
						ClearKeepBMP();
					}
				}
			}
#endif
			if(f_rpcolor == 5){
				 int reserve_b_bcolor; // since creared by ClearKeep...
				 ChgPage(s_PPage);

				 f_rpcolor = 0;			// Get page color //
				 f_spsh = -1;
				 ExpandPage0();
				 count = f_bcolor;
				 reserve_b_bcolor = f_b_bcolor;
				 ClearKeepBMP();
				 ClearKeepBMP();
				 f_bcolor = count;
				 f_b_bcolor = reserve_b_bcolor;
				 f_rpcolor = 5;
#if	PDEBUG
				 if((f_bcolor & 0xffffff) != 0xffffff){
					RECT rc;
					HBRUSH hbrBackground;
					hbrBackground = CreateSolidBrush(
						RGB((f_bcolor>>16) & 0xff, (f_bcolor>>8) & 0xff, 
							f_bcolor & 0xff));
					rc.top = 0;
					rc.right  = (rc.left = right_shift) + logw;	/* + cxDib */
					rc.bottom = logh;
					FillRect(pPD->hDC, &rc, hbrBackground);
					DeleteObject(hbrBackground);
				} else if( f_b_bcolor == 0 ) {
					RECT rc;
					rc.top = 0;
					rc.right  = (rc.left = right_shift) + logw;	/* + cxDib */
					rc.bottom = logh;
					FillRect(pPD->hDC, &rc, GetStockObject(BLACK_BRUSH));
				}
				InitTTOut(pPD->hDC, right_shift - L_M, -T_M, 1, 1);
				ExpandPage0();
#else
			error(C_MSG, "page %d(%d):mode %x\n", s_PPage, right_shift, s_mode);
#endif
				goto next;
			}
			if(s_PPage != GetCurrentPage()
				|| new_enlarge
				|| old_mode != SetParaSection(-1)
				|| old_rpc != f_rpcolor){

				ChgPage(s_PPage);
				ExpandPage0();			/* */
			}
#ifdef	CUT_SPACE
//			if(f_rpcolor != 4)
			{
				GetBoundingBox((BUFFER*)(bitmap_buf_pointer->start),
					GetTextXSize(), (GetBufXSize() + 7)/8, GetTextYSize(), 
					&bx);
				if(bx.left < 0)
					goto patch;
				if(bx.left < L_M)
					bx.left = L_M;
				lm = bx.left - L_M;
				if(logw > bx.right - bx.left + 1)
					logw = bx.right - bx.left + 1;
				if(bx.top < T_M)
					bx.top = T_M;
				tm = bx.top - T_M;
				if(logh > bx.bottom - bx.top + 1)
					logh = bx.bottom - bx.top + 1;
			}
#else
				tm = lm = 0;
#endif
			if((pDib = GetWindowBMP( L_M + lm, T_M + tm, logw, logh, 
			  1, 1, NULL )) == NULL){
				MessageBox( g_winData.hMainWnd, "Error in Expanding a page", 
					NULL, MB_OK );
				goto err;
			}
			pDib += sizeof(BITMAPFILEHEADER);
			pDibBits = GetDibBitsAddress( pDib );
			cxDib	 = GetDibWidth( pDib );
			cyDib	 = GetDibHeight( pDib );
#if	PDEBUG
			nError = SetDIBitsToDevice( pPD->hDC,
						right_shift + lm, tm,
						cxDib, cyDib, 
						0, 0,
						0, cyDib, 
						(LPSTR)pDibBits, (LPBITMAPINFO)pDib, 
						DIB_RGB_COLORS );
#else
			error(C_MSG, "page %d(%d):mode %x\n", s_PPage, right_shift, s_mode);
#endif
//			if(f_rpcolor == 4)
				free_bmp( pDib - sizeof(BITMAPFILEHEADER));

senderr:	if( !nError )
			{
				char error[128];
				wsprintf( error, "Error \nCode = %d", GetLastError() );
				MessageBox( g_winData.hMainWnd, error, NULL, MB_OK );
				goto err;
			}
patch:		for(count = 0; ; ){
				type = 0;
				pBMP = (BYTE *)GetBMPdata(count++, &x_pos, &y_pos, 
					&x_size, &y_size, &type);
				if(pBMP == NULL)
					break;
				x_pos += right_shift - L_M;
				y_pos -= T_M;
#ifdef	WMF
				if(type == F_WMF || type == F_EMF){
					DisplayMetaFile(pPD->hDC, pBMP, x_pos, y_pos, 
						x_size, y_size, type);
					continue;
				}
#endif
				x_org	= GetDibWidth( pBMP );
				y_org	= GetDibHeight( pBMP );
				x_cut1 = right_shift - x_pos;
				if(x_cut1 < 0)
					x_cut1 = 0;
				x_cut2 = x_size	 + x_pos + L_M - (dev_w - R_M);
				if(x_cut2 < 0)
					x_cut2 = 0;
				y_cut1 = -y_pos;
				if(y_cut1 < 0)
					y_cut1 = 0;
				y_cut2 = y_size + y_pos + T_M - (dev_h - B_M);
				if(y_cut2 < 0)
					y_cut2 = 0;
				if(	 (x_cutsize = x_size - x_cut1 - x_cut2) <= 0
				  || (y_cutsize = y_size - y_cut1 - y_cut2) <= 0)
				  continue;
				f_and = (type==1)?SRCCOPY:((type > -3)?SRCAND:SRCPAINT);
				ws = x_org*x_cutsize/x_size;	/* 転送元矩形左下隅ｘ座標 */
				hs = y_org*y_cutsize/y_size;	/* 転送元矩形左下隅ｙ座標 */
				x_cut1o = x_cut1*x_org/x_size;
				y_cut2o = y_cut2*y_org/y_size;
				if(ws + x_cut1o > x_org)
					ws = x_org - x_org;
				if(hs + y_cut2o > y_org)
					hs = y_org - y_cut2o;
				nError = PrintKeepBMP(pPD->hDC, hMemDC, pBMP, type, f_and,
					x_pos + x_cut1, y_pos + y_cut1, x_cutsize, y_cutsize,
					x_cut1o, y_cut2o, ws, hs, y_org);
				if(!nError)
					goto senderr;
			}
next:		if(page_macro){
				if(repeat != 0 || !f_fukuro)
					break;
				s_PPage = s_PPage2;
			}else{
				if(step == 1 || step == -1 || repeat != 0 || !f_fukuro)
					break;
				s_PPage++;
			}
			right_shift = (!right_shift)?dist:0;
			repeat++;
		}
#if	PDEBUG
		nError = EndPage( pPD->hDC );
		if( nError <= 0 )
		{
			/* When printing job is canseled by user, I don't know why,
			   an error will happen in EndPage procedure. So in following
			   we check bPrint is FALSE, and if so, we call AbortDoc
			   and exit error handling and printing job. */
			if( bPrint == FALSE )
			{
				AbortDoc( pPD->hDC );
				goto err;
			}
			/* if bPrint != FALSE, because user want to print out DVI files,
			   this error must be serious one, but I don't know how to do. */
			MessageBox( g_winData.hMainWnd, "an error on EndPage",
								 NULL, MB_OK | MB_ICONSTOP );
			goto err;
		}
#else
	error(C_MSG, "Now print\n");
#endif
		if(page_macro){
			s_PPage = GetPrintPage(NULL, pPD->nFromPage, pPD->nToPage, &f_mode);
			if(f_fukuro)
				s_PPage2 = GetPrintPage(NULL, pPD->nFromPage, pPD->nToPage, &f_mode);
		}else
			s_PPage = (left_page += step);
		if(!(s_mode & UNITEMODE) || f_mode)
			break;
	}
	if(closed_job == TRUE)
		goto end;
#if	PDEBUG
	if( bPrint == FALSE )
	{
		AbortDoc( pPD->hDC );
	}
	else
	{
		nError = EndDoc( pPD->hDC );
		if( nError <= 0 )
		{
			MessageBox( g_winData.hMainWnd, "an error on EndDoc",
						NULL, MB_OK | MB_ICONSTOP );
err:		result = FALSE;
		}
	}
	if(result != FALSE && (!(s_mode & UNITEMODE) || f_mode) ){
		closed_job = TRUE;
		goto repeat_job;
	}
#else
	if(result != FALSE && (!(s_mode & UNITEMODE) || f_mode)){
		closed_job = TRUE;
		goto repeat_job;
	}
err: result = FALSE;
#endif
end: 
	paper_width = 0;
	if(f_rpcolor == 5){
		InitTTOut(NULL, 0, 0, 1, 1);
		paper_width = 1;
	}
	EnableWindow( g_winData.hMainWnd, TRUE );
	DestroyWindow( hCancelDlg );
	ClearhBitmap();
	DeleteDC( pPD->hDC );
	if(print_dpi){
		SetParaInt("dpi", old_xdpi);
		if(old_xdpi != old_ydpi)
			SetParaInt("dpi",  old_ydpi);
		paper_width = 1;
	}
	if(old_mode != SetParaSection(-1)){
		SetParaSection(old_mode);
		ReSetMetric();
		if(old_para >= 0){
			SetParaString("y", !strcmp(old_y, "A4")?"A5":"A4");
			KeepPara(old_para);
		}else
			RestoreRegistry();
		paper_width = 1;
	}
	SetParaFlag("gfit", old_gfit);
	if(new_enlarge){
		new_enlarge = 0;
		SetParaInt("e", old_enlarge);
		SetParaFlag("varf", old_resize);
		OX = old_ox;
		OY = old_oy;
		ReSetMetric();
		SetParaString("y", !strcmp(old_y, "A4")?"A5":"A4");
		SetParaString("y", old_y);
		paper_width = 1;
	}
	bright = org_bright;
	f_rpcolor = old_rpc;
	SetGamma(gamma);
	if(	 paper_width || GetCurrentPage() != OrigPage || old_gfit != FALSE
	  || f_rpcolor == 0 || f_rpcolor == 5 || reserve_2page_mode ){
		ClearKeepBMP();
		ChgPage(OrigPage);
		ExpandPage();
		f_2page = reserve_2page;
		if( (reserve_2page_mode & F_2PAGE) && (!IS_MPAGE && !IS_16PAGE) )
			if( reserve_2page_mode & F_2REV ){
				SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_RDOUBLE, 0 );
				SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_RDOUBLE, 0 );
			} else{
				SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_DOUBLE, 0 );
				SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_DOUBLE, 0 );
			}
		else if( IS_MPAGE && IS_16PAGE )
			SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_16PAGE, 0 );
		else if( IS_MPAGE )
			SendMessage( g_winData.dviwin.hWnd, WM_COMMAND, ID_CROSS, 0 );
	}
	return result;
}

static void ShowReduce( HWND hDlg )
{
	EnableWindow( GetDlgItem( hDlg, IDC_ADJORIG ), new_enlarge != 1000 );
}

static void ShowDist( HWND hDlg )
{
	char tmp[32];

	sprintf(tmp, (new_dist < 0)?"":"W:%2d.%02dcmx2",
		new_dist/100, new_dist - (new_dist/100)*100);
	SetDlgItemText( hDlg, IDC_DISTANCE, tmp);
}

int GetLPTName(char *s, int lpt)
{
	char *p;
	static char *current_printer = NULL;

	if (s == NULL) {	/* save the current printer */
		LPDEVNAMES dn;
		Free0(current_printer);
		if (pd.hDevNames != NULL) {
			dn = GlobalLock(pd.hDevNames);
			current_printer = dup_string((LPSTR)dn + dn->wDeviceOffset);
			GlobalUnlock(pd.hDevNames);
		} else {
			current_printer = NULL;
		}
		return 0;
	}
	if (lpt == 0 && current_printer) {	/* current printer */
		strcpy(s, current_printer);
		return 0;
	}
	if(lpt <=0){						/* default printer */
		if(GetProfileString("windows", "device", "", s, 256) > 0 && 
		  (p = strchr(s, ',')) != NULL ){
			*p = '\0';
			while( (p = strstr(p+1, "LPT")) != NULL){
				p += 3;
				if(strstr(p, "LPT"))
					continue;
				return *p - '0';
			}
		}
		return -1;
	}else
		sprintf(s, "LPT%d", lpt);
	return lpt;
}

static char *PaperL[] =
{
	"Default",
	"Auto",
	"Hand",
	"Lower",
	"Upper"
}
;

static char *PaperM[] = 
{
	"Default",
	"Normal",
	"Option"
};

// CallBack from  PrintHookProc
BOOL CALLBACK DlgDviprtProc(HWND hdwnd, UINT message, UINT wParam, LONG lParam)
{
	static int type;
	int s_pos, num, tmp;
	char fig[16];
	char *msg;
	static HWND udWnd[2];
	static HWND hedit, hcombo, hstatic;

//	#define	LAST_SIZE (sizeof(papersize_str)/sizeof(char *))
//  #	define	LAST_SIZE 10
	#	define	LAST_SIZE 29

	switch(message){
		case WM_INITDIALOG:
			type = -1;
			hedit = GetDlgItem( hdwnd, IDC_DVIPRT );
			SetFontJE(hedit);
			hcombo = GetDlgItem( hdwnd, IDC_SPAPER );
			SetFontJE(hcombo);
			hstatic = GetDlgItem( hdwnd, IDC_LPT );
			SetFontJE(hstatic);
			SetMargin(hedit);
			SetMargin(GetDlgItem(hdwnd,IDC_Y));
			SetMargin(GetDlgItem(hdwnd,IDC_PW));
			SetMargin(GetDlgItem(hdwnd,IDC_PH));
			SetMargin(GetDlgItem(hdwnd,IDC_DVIPRT));
			for(s_pos = 0; s_pos < LAST_SIZE; )
				SendDlgItemMessage(hdwnd, IDC_Y, CB_ADDSTRING, 0,
					(LPARAM)papersize_str[s_pos++]);
			for(s_pos = 0; s_pos < LAST_SIZE; s_pos++){
				if(trans_papersize[s_pos] == (op_y & 0xff))
					break;
			}
			if(s_pos >= LAST_SIZE)
				s_pos = LAST_SIZE - 1;
			SendDlgItemMessage(hdwnd, IDC_Y, CB_SETCURSEL, s_pos, 0);
			for(num = 0; num < 2; num++){
				tmp = (!num)?op_w:op_h;
				udWnd[num] = CreateUpDownControl(
					WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
					| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
					50, 22, 20, 20, 
					hdwnd,
					ID_UPDOWN,
					g_winData.hInstance,
					(HWND)GetDlgItem( hdwnd, IDC_PW + num ),
//					200000, 20, tmp );
					0x7fff, 20, tmp );
/*!!
  On the document of CreateUpDownControl(), the arguments are "int".
  But it is, maybe, signed 16-bits integer even on WindowsNT/2000 system.
  20000(0x30D40) means 0xD40, hence the maximum value was 3392.
  (Recall that 14in (height of Legal paper) is 3556mm, longer than 3392!)
  Now it is 0x7fff = 32767/100cm.
  Are there any pieces of paper longer/wider than 3.27m? !! 2001/01/08 */
			}
			if(op_done)
					tmp = (op_done==1)?IDC_RADIOBUTTON21:IDC_RADIOBUTTON22;
			else
				tmp =	(f_rotate || (op_y & 0x300))?
					IDC_RADIOBUTTON22:IDC_RADIOBUTTON21;
			CheckRadioButton(hdwnd, IDC_RADIOBUTTON21, IDC_RADIOBUTTON22, tmp);
			SetDlgItemText(hdwnd, IDC_DVIPRT, dviprtx);
/*
sprintf(common_work + 0x100, "LPT%d", 
			GetLPTName((char *)common_work, f_lpt) );
DeviceCapabilities(common_work,common_work + 0x100, DC_ENUMRESOLUTIONS,
	common_work + 0x200, NULL);
error(14, "%d", *((int *)(common_work + 0x200)));
*/
			GetLPTName((char *)common_work, f_lpt);
			SetDlgItemText(hdwnd, IDC_LPT, common_work);

sel:		tmp = (s_pos < LAST_SIZE - 1)?FALSE:TRUE;
			EnableWindow(udWnd[0], tmp);
			EnableWindow(GetDlgItem(hdwnd, IDC_PW), tmp);
			EnableWindow(udWnd[1], tmp);
			EnableWindow(GetDlgItem(hdwnd, IDC_PH), tmp);

selprt:		GetDlgItemText(hdwnd, IDC_DVIPRT, common_work, 0x400);
			tmp = 0;
			if(*common_work == '`'){
				tmp = 1;
				s_pos = tolower(common_work[1]);
				if(s_pos != type){
					SendDlgItemMessage(hdwnd, IDC_SPAPER, 
						CB_RESETCONTENT, 0, 0);
					if( (type = s_pos) == 'l'){
						for(s_pos = 0; s_pos < 5; )
							SendDlgItemMessage(hdwnd, IDC_SPAPER, CB_ADDSTRING,
								 0, (LPARAM)PaperL[s_pos++]);
							SendDlgItemMessage(hdwnd, IDC_SPAPER, CB_SETCURSEL,
								 paper_spl, 0);
					}else if(type == 'm'){
						for(s_pos = 0; s_pos < 3; )
							SendDlgItemMessage(hdwnd, IDC_SPAPER, CB_ADDSTRING,
								 0, (LPARAM)PaperM[s_pos++]);
							SendDlgItemMessage(hdwnd, IDC_SPAPER, CB_SETCURSEL,
								 paper_mspl, 0);
					}
				}
				switch(type){
					case 'o':	msg = "Optional"; break;
					case 'e':	msg = "ESC/P"; break;
					case 'n':	msg = "NM"; break;
					case 'p':	msg = "PC-PR"; break;
					case 'l':	msg = strstr(common_work, "D600")?
										"LIPS IV":"LIPS III"; break;
					case 'm':	msg = "ESC/Page"; break;
					default :	msg = "???"; break;
				}
				sprintf(common_work, "Raw mode for %s printer(%s dpi)", msg, 
					(common_work[1]>='A'&&common_work[1]<='Z')?
					"default":"current");
			}else
				strcpy(common_work, "Execute outer program");
			EnableWindow(GetDlgItem(hdwnd, IDC_LPT), tmp); 
			SetDlgItemText( hdwnd, IDC_RAWOUT, common_work);
			return (num)?TRUE:FALSE;

		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_PHELP:
					ShowWinHelp(IDH_USEDVIPRT);
					break;

				case IDC_PRTCFG:
					if( (msg = QueryCfgName()) != NULL){
						sprintf(common_work, "`o%s",msg);
						SetDlgItemText(hdwnd, IDC_DVIPRT, common_work);
					}
					ToDviDir();
					break;

				case IDC_PSELECT:
					if(f_lpt++ == 4)
						f_lpt = 0;
					GetLPTName((char *)common_work, f_lpt);
					SetDlgItemText(hdwnd, IDC_LPT, common_work);
					break;

				case IDOK:
					op_done = (IsDlgButtonChecked( hdwnd, 
							IDC_RADIOBUTTON21))?1:2;
//					op_y = (op_y & ~0xf)|
					op_y = (op_y & ~0xff)|
							trans_papersize[SendDlgItemMessage(hdwnd, IDC_Y,
								CB_GETCURSEL, 0, 0L)];
					op_w = GetDlgItemInt( hdwnd, IDC_PW, &tmp, TRUE);
					op_h = GetDlgItemInt( hdwnd, IDC_PH, &tmp, TRUE);
					if(type == 'l' || type == 'm'){
						f_psupply = SendDlgItemMessage(hdwnd, IDC_SPAPER, 
							CB_GETCURSEL, 0, 0);
						if(type == 'l')
							paper_spl = f_psupply;
						else
							paper_mspl = f_psupply;
						if(type != 'm' || !f_psupply)
							f_psupply--;
					}else
						f_psupply = -1;
					GetDlgItemText( hdwnd, IDC_DVIPRT, dviprtx, 384);
					sprintf(fig, "%d", f_lpt);
					SetParaStringDirect("P", fig);

				case IDCANCEL:
					EndDialog(hdwnd, 0);
					return TRUE;
			}
			switch(HIWORD(wParam)){
				case CBN_SELCHANGE:
					num = 0;
					s_pos = SendDlgItemMessage(hdwnd, IDC_Y,
							CB_GETCURSEL, 0, 0L);
					goto sel;

				case EN_CHANGE:
					if(LOWORD(wParam) == IDC_DVIPRT){
						num = 0;
						goto selprt;
					}
			}
			break;

		case WM_DESTROY:
			ReSetFont(hedit);
			ReSetFont(hcombo);
			ReSetFont(hstatic);
			break;

	}
	return 0;
}

static HWND	hPrintDlg;
static HWND fromPWnd;
static HWND toPWnd;
static HWND udWnd;
static UINT	idTimer;
static UINT	idTimerc;
static int	f_ddecpy;
static int	f_ujob;

static void CALLBACK TimerProcc(HWND hWnd, UINT uMsg, UINT idEvent,
	 DWORD dwTime)
{
	char cbuf[16];

	if(f_ddecpy > 0){
		sprintf(cbuf, "%d", f_ddecpy);
		SendDlgItemMessage(hPrintDlg, edt3, WM_SETTEXT, 0,
			(LPARAM)(LPCTSTR)cbuf);
		f_ddecpy = -1;
	}else if(f_ujob >= 0){
			CheckDlgButton(hPrintDlg, IDC_UNITEJOB, f_ujob);
			f_ujob = -1;
	}else if(idTimerc && KillTimer(g_winData.hMainWnd, idTimerc))
		idTimerc = 0;
}

static void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
	if(idTimerc != 0)
		TimerProcc(hWnd, uMsg, idEvent, dwTime);
	else
		SendMessage(hPrintDlg, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0);
}

void ExecPrint(char *msg)
{
	HWND hDlg;
	char *s, *cmd;
	int i, k, b, n;

	static char *prtcmd[] =
	{
		"From", "To", "Copies", "Reduce",
		"Odd", "Even", "U2page",
		"Ujob", "Reverse", "Collate", 
		"BlankTop", "RightToLeft", "dviprt", 
		"OK"
	};
	static char cmd_buf[1024];
	f_ddecpy = f_ujob = -1;

	if(msg != NULL){
		strcpy(cmd_buf, msg);
		return;
	}
	for(cmd = cmd_buf; *cmd; ){
		for(k = 0; k < sizeof(prtcmd)/sizeof(char *); k++){
			for(i = 0, s = prtcmd[k]; *s; s++)
				if(cmd[i++] != *s)
					goto nxtkey;
			if(cmd[i++] == ':'){		/* find key */
				for(cmd += i; *cmd && *cmd <= ' '; cmd++);
				b = 1;
				switch(k){
					case 0:	hDlg = fromPWnd;
setnumber:					n = atoi(cmd);
							PostMessage( hDlg, UDM_SETPOS, 0, n );
skip:						while(*cmd > ' ')
								cmd++;
							while(*cmd && *cmd <= ' ')
								cmd++;
							break;
					case 1:	hDlg = toPWnd;
							goto setnumber;
					case 2:	f_ddecpy = atoi(cmd);
stm:						if(!idTimerc)
								SetTimer(g_winData.hMainWnd, 
									idTimerc = 6, 450, (TIMERPROC)TimerProcc);
//							goto setnumber;		// not valid
//							SetDlgItemInt(hPrintDlg, edt3, 2, 0); 
//							PostMessage(GetDlgItem(hPrintDlg, edt3), 
//								WM_SETTEXT, 0, (LPARAM)(LPCTSTR)"3");
							goto skip;
					case 3:	hDlg = udWnd;
							goto setnumber;
					case 4:	CheckDlgButton(hPrintDlg, IDC_NORMAL_PRINT, 0);
							CheckDlgButton(hPrintDlg, IDC_ODD_ONLY, 1);
							CheckDlgButton(hPrintDlg, IDC_EVEN_ONLY, 0);
							break;
					case 5:	CheckDlgButton(hPrintDlg, IDC_NORMAL_PRINT, 0);
							CheckDlgButton(hPrintDlg, IDC_ODD_ONLY, 0);
							CheckDlgButton(hPrintDlg, IDC_EVEN_ONLY, 1);
							break;
					case 6:	n = IDC_SIDEBYSIDE;
							CheckDlgButton(hPrintDlg, IDC_NORMAL_PRINT, 0);
							CheckDlgButton(hPrintDlg, IDC_ODD_ONLY, 0);
							CheckDlgButton(hPrintDlg, IDC_EVEN_ONLY, 0);
							EnableWindow( GetDlgItem( hPrintDlg,IDC_TOPBLANK ),
								TRUE );
							EnableWindow( GetDlgItem( hPrintDlg, IDC_HALF ), 
								TRUE );
							PostMessage(hPrintDlg,	WM_COMMAND, 
								MAKEWPARAM(n, 0), 0);
chkb:						CheckDlgButton(hPrintDlg, n, b );
							break;
					case 7: if(*cmd == '0'){
								f_ujob = 0;
								cmd++;
							}else if(*cmd == '1'){
								f_ujob = 1;
								cmd++;
							}
							while(*cmd && *cmd <= ' ')
								cmd++;
							goto stm;
					case 8:	n = IDC_REVERSE_ORDER;
							goto chkb;
					case 9: n = chx2;
							goto chkb;
					case 10: n = IDC_TOPBLANK;
							goto chkb;
					case 11: n = IDC_HALF;
							goto chkb;
					case 12:
							if(*cmd == '0' || *cmd == '1'){
								if(exec_dviprt && *exec_dviprt == '+'){
									if(*cmd == '0'){
										f_exec_dviprt = -1;
									}
								}else if(*cmd == '1'){
									f_exec_dviprt = 1;
								}
								while(*++cmd && *cmd <= ' ');
							}
							break;
					case 13: if(*cmd >= '0' && *cmd <= '9'){
								n = atoi(cmd);
								if(n > 1200)
									n = 1200;				/* 2 min */
							}else
								n = -1;
							SetTimer(g_winData.hMainWnd, idTimer = 5, 
								(n <= 0)?1000:n*100, (TIMERPROC)TimerProc);
							if(n >= 0)
								goto skip;
							break;
				}	/* endof switch() */

				goto nxtcmd;
			}		/* end of find key */
nxtkey:		;
		}
		cmd_buf[0] = 0;		/* corresponds to no key */
		return;
nxtcmd:	;
	}
	cmd_buf[0] = 0;
}

char *FindFirstW32(char *);
char *FindNextW32(void);

// CallBack from  PrintHookProc
BOOL CALLBACK DlgPageMacroProc(HWND hdwnd, UINT message, UINT wParam, LONG lParam)
{
#define	MAX_MACRO	128
#define	MAX_MSG		256
	int i, j, k, ch;
	char msg[MAX_MSG];
	char *s;
	FILE *fp;
	static int max_macro, mode;
	static char path[MAX_PATH];
	static char *mac;
	static HWND hedit, hcombo;

	switch(message){
		case WM_INITDIALOG:
			mode = 0;
			hedit = GetDlgItem( hdwnd, IDC_DVIPRT );
			hcombo = GetDlgItem( hdwnd, IDC_LISTBOX1 );
			SetFont( 10, hcombo, IsJapanese()?"ＭＳ ゴシック":"Courier New", IsJapanese() );
			SetMargin(hedit);
			SetMargin(GetDlgItem( hdwnd, IDC_DVIPRT));

renew:		SetPath(path,mode?"^x\\par\\*.pgn":"^x\\par\\*.pgm");
			max_macro = 0;
			common_work[0]=0;
			SendDlgItemMessage(hdwnd, IDC_LISTBOX1, LB_RESETCONTENT, 0, 0); 
			if(!mode){
				SendDlgItemMessage(hdwnd, IDC_LISTBOX1, LB_ADDSTRING, 0,
					(LPARAM)"Input by User");
				max_macro++;
			} 
			EnableWindow(GetDlgItem(hdwnd, IDC_ERACE), mode);
			EnableWindow(GetDlgItem(hdwnd, IDC_EDIT10), mode);
			for(s = FindFirstW32(path); s != NULL && max_macro < MAX_MACRO;
			  s = FindNextW32()){
				sprintf(path, "^x\\par\\%s", s);
				if((fp = fopenf(path, "r")) != NULL){
					*msg = i = 0;
					while(!i && fgets(msg, MAX_MSG, fp) && *msg=='#'){
						if(msg[2]=='#'){
							switch(msg[1]){
								case 'j':
									i = f_English?0:3;
									break;
								case 'e':
									i = f_English?3:0;
									break;
								default:
									i = 1;
							}
						}else
							i = 1;
					}
					fclose(fp);
					if(i){
						strcat(common_work, s);
						strcat(common_work, "\n");
						j = strlen(msg);
						while(j > 0 && msg[--j] <= ' ' && msg[j] > 0)
							msg[j] = 0;
						SendDlgItemMessage(hdwnd, IDC_LISTBOX1, LB_ADDSTRING, 0,
						  (LPARAM)msg+i); 
						max_macro++;
					}
				}
			}
			FindFirstW32(NULL);
			if(mac)
				Free0(mac);
			mac = dup_string(common_work);
			SendDlgItemMessage(hdwnd, IDC_LISTBOX1, LB_SETCURSEL, 0, 0);
			EnableWindow(GetDlgItem(hdwnd, IDC_DVIPRT), !mode);
			if(!mode)
				SetFocus(GetDlgItem(hdwnd, IDC_DVIPRT));
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_PHELP:
					ShowWinHelp(IDH_PAGEOPTION);
					break;

				case IDC_HIDDEN:
					mode = 1 - mode;
					SetDlgItemText(hdwnd, IDC_HIDDEN, mode? "->Curr&ent":"->Hidd&en");
					SetDlgItemText(hdwnd, IDC_ERACE, mode? "&Appear":"Hi&de");
					SetDlgItemText(hdwnd, IDOK, mode? "Ki&ll":"O&K");
					goto renew;

				case IDC_EDIT10:
				case IDC_ERACE:
				case IDC_CHKMAC:
				case IDOK:
					i = SendDlgItemMessage(hdwnd, IDC_LISTBOX1,
						LB_GETCURSEL, 0, 0L) + mode;
					if(!i){
						GetDlgItemText(hdwnd, IDC_DVIPRT, common_work+1, 0x1000);
						common_work[0] = 1;
					}else if(i>0 && i < max_macro+mode){
						s = mac;
						while(--i){
							while(*s && *s++ != '\n');
						}
						while(s[i] && s[i] != '\n')
							i++;
						ch = s[i];
						s[i] = 0;
						sprintf(common_work, "@^x\\par\\%s", s);
						s[i] = ch;
					}else
						break;
					SetPath(path, common_work+1);
					if(LOWORD(wParam) == IDC_EDIT10){
						if(i)
							EditFile(path);
						break;
					}
					if(LOWORD(wParam) == IDC_ERACE || (LOWORD(wParam) == IDOK && mode)){
						strcpy(common_work, path);
						if(LOWORD(wParam) == IDOK){		// Kill
							if(!AskYes(common_work, "Erace the above Print-Macro file?"))
								break;
							unlink(common_work);
							goto renew;
						}
														// Hide/Appear
						common_work[strlen(common_work) - 1] = mode?'m':'n';
						if(rename(path, common_work)){
							if(!access(common_work, 0) && MessageBox( g_winData.hMainWnd, 
							  common_work, 
							  "Duplicate file exists!\nErace the above?", 
							  MB_OKCANCEL) == IDOK ){
								unlink(common_work);
								if(!rename(path, common_work))
									goto renew;
							}
							error(WARNING, "Cannot rename %s", path);
								break;
						}
						goto renew;
					}
					Free0(page_macro);
					page_macro = dup_string(common_work);
					if(LOWORD(wParam) == IDOK){
						Free0(mac);
						mac = NULL;
						EndDialog(hdwnd, 0);
						return TRUE;
					}
					*common_work = 0;
					for(j=1, i = GetPrintPage(page_macro, from_page, to_page, &ch); ;
						j++, i = GetPrintPage(NULL, from_page, to_page, &ch)){
						*msg = 0;
						if(j < 256){
							if(i > 0)
								sprintf(msg, "%3d%c", i, ch?'/':' ');
							else if(i == -1)
								sprintf(msg, "  %c%c", '*', ch?'/':' ');
							else if(i == -2)
								sprintf(msg, "\nOut of Range!");
							strcat(common_work, msg);
						}
						if(i == 0 || i <= -2 || j == 1024){
							if(j >= 256){
								strcat(common_work, "-->");
								if(j < 1024){
									sprintf(msg, " %3d", k);
									strcat(common_work, msg);
								}
							}
							sprintf(common_work+(COMMON_SIZE-0x400), "Output Pages by %s", path);
							MessageBox(hdwnd, common_work, common_work+(COMMON_SIZE-0x400), MB_OK);
							break;
						}
						if(!(j & 0x0f) && j <= 256)
							strcat(common_work, "\n");
						k = i;
					}
					Free0(page_macro);
					page_macro = NULL;
					break;

				case IDCANCEL:
					Free0(page_macro);
					Free0(mac);
					page_macro=mac=NULL;
					EndDialog(hdwnd, 0);
					return TRUE;
			}
			switch(HIWORD(wParam)){
				case LBN_SELCHANGE:
					if(!mode){
						i = SendDlgItemMessage(hdwnd, IDC_LISTBOX1,
							LB_GETCURSEL, 0, 0L);
						EnableWindow(GetDlgItem(hdwnd, IDC_DVIPRT), !i);
						SetFocus(GetDlgItem(hdwnd, IDC_DVIPRT));
						EnableWindow(GetDlgItem(hdwnd, IDC_ERACE), i!=0);
						EnableWindow(GetDlgItem(hdwnd, IDC_EDIT10), i!=0);
					}
					break;
			}
			break;

		case WM_DESTROY:
//			ReSetFont(hedit);
			ReSetFont(hcombo);
			break;

	}
	return 0;
}

static void SetPrtWindow(HWND hDlg, int mode)
{
	EnableWindow( GetDlgItem( hDlg, IDC_NORMAL_PRINT ), mode&1 );
	EnableWindow( GetDlgItem( hDlg, IDC_ODD_ONLY ), mode&1 );
	EnableWindow( GetDlgItem( hDlg, IDC_EVEN_ONLY ), mode&1 );
	EnableWindow( GetDlgItem( hDlg, IDC_SIDEBYSIDE ), mode&1 );

	EnableWindow( GetDlgItem( hDlg, IDC_REDUCE0 ), mode&2 );
	EnableWindow( GetDlgItem( hDlg, IDC_REDUCE1 ), mode&2 );
	EnableWindow( GetDlgItem( hDlg, IDC_REDUCE2 ), mode&2 );
	EnableWindow( GetDlgItem( hDlg, IDC_OTHERS ), mode&2 );
	if(!IsDlgButtonChecked(hDlg, IDC_SIDEBYSIDE))
		mode = 0;
	EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), mode&1 );
	EnableWindow( GetDlgItem( hDlg, IDC_HALF ), mode&1 );
}

BOOL APIENTRY PrintHookProc( 
	HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	/* This procedure must return FALSE if the message needs to be disposed by
	   standard dialog box procedure. */
	static HWND lrWnd;
	static HWND cpWnd;
	static HWND hEboxWnd;
	static int red[3];
	static int f_red;
	static int f_rad2;
	static int f_frad2;
	static int total_page;
	static int max_page;
	static int f_others;
	static int f_show;
	static int f_dounite;
	static BOOL f_col;
	static BOOL f_copy;
	static HWND hedit1, hedit2, hedit3, hcombo, hradio, hedit4, hedit5, hedit6;
	static char buf_name[0x100];
	static RECT p_rec;
	RECT	p_rec2;


	static int mag_red[] = {1000, 500, 1224, 1414, 2000};
	int tmp, op;
	double opp;
	DWORD sec_cl, by_sec, free_cl, all_cl;
	char *tdir;
	char tmp_page[16];

	switch( message )
	{
		case WM_INITDIALOG:
		{
//			int wd, ht;
			char *lp1;
			char *lp2;
			char *pp;

			hcombo = GetDlgItem( hDlg, 1136 ); // quality
			hedit1 = GetDlgItem( hDlg, 1088 ); // printer
			hradio = GetDlgItem( hDlg, 1056 ); // "All Page"
			hedit2 = GetDlgItem( hDlg, IDC_PRINTFROM ); // (FROM)
			hedit3 = GetDlgItem( hDlg, IDC_PRINTTO ); // (TO)
			hedit4 = GetDlgItem( hDlg, IDC_RED2 ); // magnify
			hedit5 = GetDlgItem( hDlg, 1152 ); // from
			hedit6 = GetDlgItem( hDlg, 1153 ); // to
			SetFont( 0, hcombo, IsJapanese()?"ＭＳ ゴシック":"Arial", IsJapanese() );
			SetFont( 0, hedit1, IsJapanese()?"ＭＳ ゴシック":"Arial", IsJapanese() );
			SetFont( 0, hradio, IsJapanese()?"ＭＳ ゴシック":"Arial", IsJapanese() );
			SetFont( 0, hedit2, "Arial", FALSE );
			SetFont( 0, hedit3, "Arial", FALSE );
			SetFont( 0, hedit4, "Arial", FALSE );
			SetFont( 0, hedit5, "Arial", FALSE );
			SetFont( 0, hedit6, "Arial", FALSE );
			SetMargin(hedit4);
			SetMargin(hedit5);
			SetMargin(hedit6);
			SetMargin(GetDlgItem(hDlg,1154));
			if(p_rec.left == p_rec.right)
				GetWindowRect(hDlg, &p_rec);
			if(idTimer && KillTimer(g_winData.hMainWnd, idTimer))
				idTimer = 0;
			hPrintDlg = hDlg;
			new_dist = -1;
			red[0] = new_enlarge = 1000;
			red[1] = 816;
			red[2] = 707;
			f_red = f_frad2 = 1;
			s_mode = op_done = f_col = f_copy = max_page = f_dounite = col_count = 0;
			if(f_others)
				f_others--;
			op = (exec_dviprt && *exec_dviprt == '+')?1:0;
			strncpy(dviprtx, (exec_dviprt && exec_dviprt[op])?
				exec_dviprt+op:
				"dvipdfm^X}x{.exe ^w -s ^a-^b \"^q\"^Y{;\"^d.pdf\"}"
				"^z^{dvipdfm (not &x)}^{View PDF &?}Make PDF by dvipdfm(x)",
/*
				"echo^-O=^t^>>^^f;"
				"dviprt^-=^f^^q^^p;"
				"copy^^t^sprn^/b;del^^t^Zdviprt(default)",
*/
				384);
			total_page = GetTotalPage();
			f_lpt = ((pp = GetParaString("P")) != NULL)? atoi(pp) : 0;

			switch(paper_type){
				case SIZE_A3:
					lp1 = "A&3 -> B4J";
					lp2 = "A3 -> A&4";
					red[1] = 865;
					break;

				case SIZE_A4:
					lp1 = "A&4 -> B5J";
					lp2 = "A4 -> A&5";
					red[1] = 865;
					break;

				case SIZE_A5:
					lp1 = "A&5 -> B6J";
					lp2 = "A5 -> A&6";
					red[1] = 865;
					break;

				case SIZE_A6:
					lp1 = "A&6 -> B7J";
					lp2 = "A6 -> A&7";
					red[1] = 865;
					break;

				case SIZE_B3:
					lp1 = "B&3J -> A3";
					lp2 = "B3J -> B&4J";
					break;

				case SIZE_B4:
					lp1 = "B&4J -> A4";
					lp2 = "B4J -> B&5J";
					break;

				case SIZE_B5:
					lp1 = "B&5J -> A5";
					lp2 = "B5J -> B&6J";
					break;

				default:
					lp1 = NULL;
			}
			mag_red[2] = (red[1] == 865)?1224:1156;
			/* For initialization of the dialog, we set radio buttons
			   to be checked normal mode, and it is all we want to do.
			   So we return TRUE not to be done by default procedure. */
			CheckRadioButton( hDlg, IDC_NORMAL_PRINT, IDC_EVEN_ONLY,
								IDC_NORMAL_PRINT );
			CheckRadioButton( hDlg, IDC_REDUCE0, IDC_REDUCE2, IDC_REDUCE0 );
			CheckDlgButton( hDlg, IDC_ADJORIG, 1);
			if(lp1 != NULL){
				SetDlgItemText( hDlg, IDC_REDUCE1, lp1);
				SetDlgItemText( hDlg, IDC_REDUCE2, lp2);
			}
			if( (hEboxWnd = GetDlgItem( hDlg, edt3 )) != NULL )
			{
			if((f_osversion & 0xff00) < (10<<8) && (f_osversion & 0xff) <= 4){
				cpWnd = CreateUpDownControl(
					WS_CHILD|WS_VISIBLE|WS_BORDER
					| UDS_SETBUDDYINT | UDS_ALIGNRIGHT|UDS_ARROWKEYS
					| UDS_NOTHOUSANDS,
					190, 64, 5, 13, 
					hDlg,
					ID_UPDOWN,
					g_winData.hInstance,
					hEboxWnd,
					500, 1, 1);
				}
			}
			fromPWnd = CreateUpDownControl(
				WS_CHILD|WS_VISIBLE|WS_BORDER
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT|UDS_ARROWKEYS
				| UDS_NOTHOUSANDS,
				190, 64, 15, 13, 
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				GetDlgItem( hDlg, edt1 ),
				total_page, 1, 1);

			toPWnd = CreateUpDownControl(
				WS_CHILD|WS_VISIBLE|WS_BORDER
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT|UDS_ARROWKEYS
				| UDS_NOTHOUSANDS,
				190, 64, 15, 13, 
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				GetDlgItem( hDlg, edt2 ),
				total_page, 1, total_page);

			lrWnd = CreateUpDownControl(
				WS_CHILD|WS_VISIBLE|WS_BORDER|UDS_HORZ|UDS_ARROWKEYS|
				WS_DISABLED | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				330, 280, 40, 40, 
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				GetDlgItem(hDlg, IDC_SDS), 
				4000, 0, 1000);

			udWnd = CreateUpDownControl(
				WS_CHILD|WS_VISIBLE|WS_BORDER
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT|UDS_ARROWKEYS
				| UDS_NOTHOUSANDS,
//				WS_CHILD|WS_VISIBLE|WS_BORDER|UDS_ARROWKEYS|UDS_ALIGNRIGHT
//				| UDS_NOTHOUSANDS,
				374, 382, 10, 18,
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				GetDlgItem(hDlg, IDC_RED2),
				4000, 300, 1000);

				EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), FALSE );
				EnableWindow( GetDlgItem( hDlg, IDC_HALF ), FALSE );
				{
					BOOL tmp = (total_page <= 1)?FALSE:TRUE;
//					EnableWindow( hEboxWnd, tmp );
					EnableWindow( GetDlgItem( hDlg, ID_MYRAD ), tmp );
					EnableWindow( GetDlgItem( hDlg, edt1 ), tmp );
					EnableWindow( GetDlgItem( hDlg, edt2 ), tmp );
					EnableWindow( GetDlgItem( hDlg, stc2 ), tmp );
					EnableWindow( GetDlgItem( hDlg, stc3 ), tmp );
//					EnableWindow( GetDlgItem( hDlg, stc5 ), tmp );
				}

			ShowReduce( hDlg );
			CheckRadioButton( hDlg, rad1, rad3, rad1 );
			if(	  (tdir = getenv("TMP"))  != NULL
			  ||  (tdir = getenv("TEMP")) != NULL)
				GetWindowsDirectory( tdir = common_work, MAX_PATH );
			sprintf(common_work, "%c:\\", *tdir);
			ExecPrint(NULL);
			if(f_exec_dviprt){
				op = (f_exec_dviprt>0)?1:0;
				f_exec_dviprt = 0;
			}
			if(op || !f_prtlarge || g_bPrintingByDVIPRT){
				MoveWindow(hDlg,
					p_rec.left, p_rec.top,
					p_rec.right - p_rec.left,
					(p_rec.bottom - p_rec.top)*156/256 + 1,
					TRUE);
				SetPrtWindow(hDlg, 0);
			}
			SetFocus(GetDlgItem(hDlg, IDOK));
			f_show = 0xfff;
			f_col  = IsWindowEnabled( GetDlgItem( hDlg, chx2 ) );
			f_copy = IsWindowEnabled( GetDlgItem( hDlg, stc5 ) );
			GetDlgItemText(hDlg, 1088, buf_name, 0x100);
			if(op || g_bPrintingByDVIPRT){
				CheckDlgButton( hDlg, IDC_DVIPRT, 1 );
				op = 0;
				goto optpr;
			}
			if(GetDiskFreeSpace( common_work, 
				&by_sec, &sec_cl, &free_cl, &all_cl)){
				opp = (double)GetTextXSize()*GetTextYSize()/4; /* byte for two pages */
				opp = opp*GetPDpi()/GetXDpi()*GetPDpi()/GetXDpi();
				if(opp > 0)
					max_page = (double)by_sec*sec_cl*free_cl/opp;
				else
					max_page = 10000;
				if( max_page > GetTotalPage()
				 || !AskYes("Unite -> Separate?", "Job for printing")){
					f_dounite = 1;
					CheckDlgButton(hDlg, IDC_UNITEJOB, 1);
				}
			}
			return FALSE;
		}
		case WM_VSCROLL:
			if((HWND)lParam == udWnd){	
get_red:		for(tmp=0; tmp < 3; tmp++)
					CheckDlgButton( hDlg, IDC_REDUCE0 + tmp, 0);
				new_enlarge = LOWORD(SendMessage(udWnd, UDM_GETPOS, 0, 0));
				if(!new_enlarge)
					new_enlarge = 1000;
				for(f_red = 3; f_red > 0; f_red--){
					if(new_enlarge == red[f_red-1])
						break;
				}
				if(f_red)
					CheckDlgButton( hDlg, IDC_REDUCE0 - 1 + f_red, TRUE);
				ShowReduce( hDlg );
			}
			return TRUE;

		case WM_HSCROLL:
			if((HWND)lParam == lrWnd && new_dist >= 0){
				new_dist = LOWORD(SendMessage(lrWnd, UDM_GETPOS, 0, 0));
				ShowDist( hDlg );
			}
			return 1;

		case WM_COMMAND:
			/* We check the status of radio buttons and two check box,
			  and return FALSE because we want default procedure to
			  process any problems. */
			switch(wParam)
			{
				int i;

				case IDOK:
					if(idTimer && KillTimer(g_winData.hMainWnd, idTimer))
						idTimer = 0;
					for( i = 0; i < 4; i++ )
					{ /* this number 4 is the number of radio buttons. */
						if( IsDlgButtonChecked( hDlg, IDC_NORMAL_PRINT + i ) )
						{ /* I regard the IDs stands in line continuously. */
							s_mode |= i;
						}
					}
					if(page_macro){
						if((s_mode & 7) != 3)
						s_mode &= ~7;
					}else{
						if((s_mode & 7) == 3){
							s_mode &= ~7;
							i = IsDlgButtonChecked(hDlg, IDC_TOPBLANK);
							if(IsDlgButtonChecked(hDlg, IDC_HALF))
								s_mode |= (i)?TOPRIGHTBLANKMODE:RIGHTLEFTMODE;
							else
								s_mode |= (i)?TOPLEFTBLANKMODE:SIDEBYSIDEMODE;
						}
						if( IsDlgButtonChecked( hDlg, IDC_REVERSE_ORDER ) )
						{ /* One can check whether reverse mode if 4th bit is on */
							s_mode |= REVERSEMODE;
						}
					}
					if( IsDlgButtonChecked( hDlg, IDC_STOPATEACHPAGE ) )
					{ /* One can check whether pause mode if 5th bit is on */
						s_mode |= PAUSEMODE;
					}else if( IsDlgButtonChecked( hDlg, IDC_UNITEJOB ) )
					{ /* One can check whether unite mode if 6th bit is on */
						s_mode |= UNITEMODE;
					}
					col_count = IsDlgButtonChecked(hDlg, chx2);
					if(new_enlarge != 1000
					  && IsDlgButtonChecked( hDlg, IDC_ADJORIG) )
						s_mode |= ADJORIGMODE;
					if( (s_mode & USEDVIPRT ) && !op_done){
						i = ((s_mode & PAGINGMODE)>=SIDEBYSIDEMODE &&
							 (s_mode & PAGINGMODE)<=RIGHTLEFTMODE)?1:0;
						op_done = (i || f_rotate)?2:1;
						op_y = Guessysize( paper_type, new_enlarge, i );
						op_w = (double)GetTextXSize()/GetXDpi()*254 + 0.5;
						op_h = (double)GetTextYSize()/GetYDpi()*254 + 0.5;
					}
					copies = GetDlgItemInt( hDlg, edt3, &i, TRUE );
					if(new_enlarge <= 0)
						new_enlarge = 1000;
					tmp = GetDlgItemInt( hDlg, IDC_RED2, &i, TRUE);
					if(tmp <= 0)
						tmp = new_enlarge;
					if(tmp != new_enlarge){
						error(ERRPAUSE,
							"Reduce/Magnify: %d.%d%% is out of range\n"
							"Replace it by %d%%",
							tmp/10, tmp - tmp/10*10, new_enlarge/10);
						SendMessage( udWnd, UDM_SETPOS, 0, new_enlarge );
						return TRUE;
					}
					f_rawfile = IsDlgButtonChecked( hDlg, chx1 ) ;
					break;

				case IDC_REDUCE0:
				case IDC_REDUCE1:
				case IDC_REDUCE2:
					f_red =	 wParam - (IDC_REDUCE0 - 1);
					SendMessage( udWnd, UDM_SETPOS, 0, 
						new_enlarge = red[f_red - 1]);
					ShowReduce( hDlg );
					if(new_dist >= 0)
						goto chg_dist;
					break;

				case IDC_OTHERS:
					if(++f_others >= sizeof(mag_red)/sizeof(int))
						f_others = 0;
					SendMessage( udWnd, UDM_SETPOS, 0, mag_red[f_others]);
					break;

				case IDC_NORMAL_PRINT:
				case IDC_ODD_ONLY:
				case IDC_EVEN_ONLY:
					EnableWindow( lrWnd, FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_HALF ), FALSE );
					tmp = GetWindowLong( GetDlgItem( hDlg, IDC_SDS ), 
						GWL_STYLE );
					SetWindowLong( GetDlgItem( hDlg, IDC_SDS ) , 
						GWL_STYLE, tmp & ~WS_TABSTOP );
					new_dist = -1;
					ShowDist( hDlg );
					break;

				case IDC_SIDEBYSIDE:
					EnableWindow( lrWnd, TRUE );
					if(!page_macro){
						EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), TRUE );
						EnableWindow( GetDlgItem( hDlg, IDC_HALF ), TRUE );
					}
					tmp = GetWindowLong( GetDlgItem( hDlg, IDC_SDS ), 
						GWL_STYLE );
					SetWindowLong( GetDlgItem( hDlg, IDC_SDS ), 
						GWL_STYLE, tmp | WS_TABSTOP );
chg_dist:			new_dist = 
						(double)GetTextXSize()/GetXDpi()*new_enlarge*0.254
						  + 0.5;
					SendMessage( lrWnd, UDM_SETPOS, 0, new_dist );
					ShowDist( hDlg );
					break;

				case IDC_DVIPRT:
					op = 0;
optpr:				tmp = !IsDlgButtonChecked( hDlg, IDC_DVIPRT );
//					EnableWindow( GetDlgItem( hDlg, psh1 ), tmp );
//					EnableWindow( GetDlgItem( hDlg, stc1 ), tmp );
					EnableWindow( GetDlgItem( hDlg, stc4 ), tmp );
					EnableWindow( GetDlgItem( hDlg, cmb1 ), tmp );
					EnableWindow( GetDlgItem( hDlg, IDC_UNITEJOB ), tmp );
optpr2:				EnableWindow( GetDlgItem( hDlg, edt3 ), !tmp );
					EnableWindow( GetDlgItem( hDlg, IDC_STOPATEACHPAGE ), tmp);
					EnableWindow( GetDlgItem( hDlg, stc1 ),
						(tmp || f_lpt == 0)? TRUE : FALSE);
					SetDlgItemText( hDlg, IDC_REVERSE_ORDER, "&Reverse order");
					SetDlgItemText( hDlg, chx1, "Print to f&ile");
					CheckDlgButton( hDlg, IDC_REVERSE_ORDER, FALSE );
					CheckDlgButton( hDlg, chx1, FALSE);
					if( tmp ){
						SetDlgItemText(hDlg, 1088, buf_name);
						s_mode &= ~USEDVIPRT;
						EnableWindow( GetDlgItem( hDlg, IDC_LARGE ), TRUE);
						EnableWindow( GetDlgItem( hDlg, ID_OPTION ), TRUE);
						EnableWindow( GetDlgItem( hDlg, chx1 ), TRUE );	
						EnableWindow( GetDlgItem( hDlg, chx2 ), f_col );
						EnableWindow( GetDlgItem( hDlg, stc5 ), f_copy );
						EnableWindow( GetDlgItem( hDlg, edt3 ), f_copy );
						EnableWindow( GetDlgItem( hDlg, IDC_REVERSE_ORDER), TRUE);
						EnableWindow( GetDlgItem( hDlg, ID_OPTION ), TRUE);
//						EnableWindow( GetDlgItem( hDlg, IDC_SIDEBYSIDE), TRUE);
						GetWindowRect(hDlg, &p_rec2);
						MoveWindow(hDlg,
							p_rec2.left, p_rec2.top,
							p_rec.right - p_rec.left, (p_rec.bottom - p_rec.top)*156/256+1,
							TRUE);
					}else{								// dviprt
						char *pt, *pt2;
						int count;

						SetPrtWindow(hDlg, 3);
						if((pt = strstr(dviprtx, "^z")) == NULL)
							pt = strstr(dviprtx, "^Z");
						if(pt){
							pt += 2;
							if(*pt == '^'){
								pt++;
								f_show = atoi(pt);
								if(*pt == '{')
									pt--;
								else while(*pt >= '0' && *pt <= '9')
									pt++;
							}
							for(count = 0; count < 2; count++){
								if(*pt == '^' && pt[1] == '{'){
									pt2 = common_work+0x1000;
									for(pt += 2; *pt && *pt != '}'; )
										*pt2 ++ = *pt++;
									*pt2 = 0;
									if(*pt)
										pt++;
									SetDlgItemText( hDlg, count?IDC_REVERSE_ORDER:chx1, 
										common_work+0x1000);
									f_show |= (count?2:0x1000);
								}
							}
							if(*pt == ' ')
								pt++;
							strcpy(common_work+0x1000, pt);
							if((pt = strchr(common_work+0x1000, ';')) != NULL)
								*pt = '\n';
							SetDlgItemText(hDlg, 1088, common_work+0x1000);
						}
						if((f_show & 0xff) < 8)
							EnableWindow( GetDlgItem( hDlg, IDC_LARGE ), FALSE);
						if(!(f_show & 0x10))
							EnableWindow( GetDlgItem( hDlg, ID_OPTION ), FALSE);
						GetWindowRect(hDlg, &p_rec2);
						MoveWindow(hDlg,
							p_rec2.left, p_rec2.top,
							p_rec.right - p_rec.left,
							(p_rec.bottom - p_rec.top)*(((f_show & 0xff) < 4)?110:156)/256+1,
							TRUE);
						EnableWindow( GetDlgItem( hDlg, chx2 ), f_show & 1);
						EnableWindow( GetDlgItem( hDlg, IDC_REVERSE_ORDER), f_show & 2);
						EnableWindow( GetDlgItem( hDlg, edt3 ), f_show & 4);
						EnableWindow( GetDlgItem( hDlg, stc5 ), f_show & 4);
						EnableWindow( GetDlgItem( hDlg, chx1 ), f_show & 0x1000);
						if(!(f_show & 0x20)){
							if(IsDlgButtonChecked(hDlg, IDC_SIDEBYSIDE)){
								CheckDlgButton(hDlg, IDC_NORMAL_PRINT, TRUE);
								CheckDlgButton(hDlg, IDC_SIDEBYSIDE,   FALSE);
								PostMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_NORMAL_PRINT, 0), 0);
							}
							EnableWindow( GetDlgItem( hDlg, IDC_SIDEBYSIDE), FALSE);
						}
						if(cpWnd != NULL)
							EnableWindow( cpWnd, TRUE );

						if(dviprtx && *dviprtx == '`'){
							EnableWindow( GetDlgItem( hDlg, chx1 ), TRUE );
							EnableWindow( GetDlgItem( hDlg, 
								IDC_STOPATEACHPAGE ), FALSE );
							if(	 tolower(dviprtx[1]) != 'l'
							  && tolower(dviprtx[1]) != 'm'){
//								EnableWindow( GetDlgItem(hDlg, stc5), FALSE );
//								EnableWindow( GetDlgItem(hDlg, edt3), FALSE );
								CheckDlgButton( hDlg, chx2, 1 );
								EnableWindow( GetDlgItem(hDlg, chx2), FALSE );
							 }
						}
						s_mode |= USEDVIPRT;
					}
					SetPrtWindow(hDlg, 0);
					if(!IsWindowEnabled( GetDlgItem(hDlg, edt3) ))
						SetDlgItemText( hDlg, edt3, "1" );
					if(op)
						return TRUE;
					ExecPrint(NULL);
					break;

				case chx2:
					col_count = IsDlgButtonChecked(hDlg, chx2);
					break;

				case rad1:
					from_page = 1;
					to_page = total_page;
					if(total_page <= 1)
						return TRUE;
					goto set_page;

				case ID_MYRAD:
					if(f_frad2)
						f_frad2 = 0;		// first time in this session
					else
						f_rad2++;
					from_page = (h_hist[RANGE_MARK].id == id_dvi)?
								h_hist[RANGE_MARK].page:GetCurrentPage();
					to_page = (h_hist[PAGE_MARK].id == id_dvi)?
						h_hist[PAGE_MARK].page:from_page;
					switch(f_rad2 - (f_rad2/4)*4){
						case 0:
							if(to_page < from_page){
								tmp = from_page;
								from_page = to_page;
								to_page = tmp;
							}
							break;
						case 1:
							to_page = from_page;
							break;
						case 2:
							from_page = to_page;
							break;
						case 3:
							to_page = from_page = GetCurrentPage();
							break;
					}
//					CheckDlgButton( hDlg, rad1, 0 );
					CheckDlgButton( hDlg, rad3, 1 );
set_page:			tmp = to_page;
					SendMessage( fromPWnd, UDM_SETPOS, 0, from_page );
					to_page = tmp;
					SendMessage( toPWnd,   UDM_SETPOS, 0, to_page );
//					SetDlgItemInt( hDlg, edt1, from_page,  FALSE );
//					SetDlgItemInt( hDlg, edt2, to_page, FALSE );
					break;

				case IDC_LARGE:
					GetWindowRect(hDlg, &p_rec2);
					if(p_rec2.bottom - p_rec2.top >=
					  (p_rec.bottom - p_rec.top)*160/256+1){
						op = 0;
						f_prtlarge = FALSE;
						goto optpr;
					}
					tmp = IsDlgButtonChecked(hDlg, IDC_DVIPRT);
					f_prtlarge = TRUE;
					MoveWindow(hDlg, p_rec2.left, p_rec2.top,
						p_rec.right - p_rec.left,
						(tmp && !(f_show & 0x40))?
							((p_rec.bottom - p_rec.top)*210)/256+1
							:(p_rec.bottom - p_rec.top),
						TRUE);
					if(!(s_mode & USEDVIPRT)){
						SetPrtWindow(hDlg, 3);
						if(page_macro)
							goto pmcr;
					}else if(f_show & 0x60){
						SetPrtWindow(hDlg, f_show>>5);
						if(page_macro)
							goto pmcr;
					}
					break;

				case ID_OPTION:
					tmp = IsDlgButtonChecked(hDlg, IDC_DVIPRT);
					if(tmp && !(f_show & 0x10))
						break;
					DialogBox( g_winData.hInstance,
						MAKEINTRESOURCE(IDD_PRTMACRO),
						hDlg, DlgPageMacroProc );
					if(!page_macro){
						if(IsDlgButtonChecked( hDlg, IDC_SIDEBYSIDE)){
							EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), TRUE );
							EnableWindow( GetDlgItem( hDlg, IDC_HALF ), TRUE );
						}
						EnableWindow( GetDlgItem( hDlg, IDC_ODD_ONLY ), TRUE );
						EnableWindow( GetDlgItem( hDlg, IDC_EVEN_ONLY ), TRUE );
						EnableWindow( GetDlgItem( hDlg, IDC_REVERSE_ORDER ), TRUE );
						break;
					}
pmcr:				EnableWindow( GetDlgItem( hDlg, IDC_TOPBLANK ), FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_HALF ), FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_ODD_ONLY ), FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_EVEN_ONLY ), FALSE );
					EnableWindow( GetDlgItem( hDlg, IDC_REVERSE_ORDER ), FALSE );
					break;

				case IDC_PHELP:
					ShowWinHelp(IDH_PRINT);
					break;

				case psh1:
					if(s_mode & USEDVIPRT){
						if(!op_done){
							for(i = 3; i < 6; i++){
								if( IsDlgButtonChecked( hDlg, 
									IDC_NORMAL_PRINT + i ) )
									break;
							}
							i = (i<6)?1:0;
							op_y = Guessysize( paper_type, new_enlarge, i );
							op_w = (double)GetTextXSize()/GetXDpi()*254 + 0.5;
							op_h = (double)GetTextYSize()/GetYDpi()*254 + 0.5;
						}
						GetLPTName(NULL, 0);
						DialogBox( g_winData.hInstance,
							MAKEINTRESOURCE(IDD_DVIPRT),
							hDlg, DlgDviprtProc );
						tmp = FALSE;
						op = TRUE;
						goto optpr2;
/*
						(dviprtx && *dviprtx == '`')?TRUE:FALSE;
						EnableWindow( GetDlgItem( hDlg, chx1 ), tmp);
						EnableWindow( GetDlgItem( hDlg, IDC_STOPATEACHPAGE ), 
							!tmp );
						op = TRUE;
						goto optpr2;
*/					}
					break;
//				default:
//					break;
			}
			if( HIWORD(wParam) == EN_CHANGE){
				if(LOWORD(wParam) == edt1 || LOWORD(wParam) == edt2){
					from_page = GetDlgItemInt( hDlg, edt1, &tmp, TRUE);
					to_page = GetDlgItemInt( hDlg, edt2, &tmp, TRUE);
					sprintf(tmp_page, "(%d)", 
						TransPage((LOWORD(wParam)==edt1)?from_page:to_page));
					SetDlgItemText(hDlg, 
						(LOWORD(wParam)==edt1)?IDC_PRINTFROM:IDC_PRINTTO, 
						tmp_page);
					if(!f_dounite)
						CheckDlgButton(hDlg, IDC_UNITEJOB, 
							(to_page - from_page < max_page)?1:0);
				}else if(LOWORD(wParam) == IDC_RED2)
					goto get_red;
			}

		case WM_DESTROY:
			ReSetFont(hcombo);
			ReSetFont(hedit1);
			ReSetFont(hradio);
			ReSetFont(hedit2);
			ReSetFont(hedit3);
			ReSetFont(hedit4);
			ReSetFont(hedit5);
			ReSetFont(hedit6);
			GetLPTName(NULL, 0);
			break;

		default:
			break;
	}
	return FALSE;
}


extern int f_GS;
extern BOOL f_gbox;
int edge_space = 16;

void CutEdge(int mode)
{
	static char *tmp_cutedge;
	int page, c_page, total;
	int f_gs, f_spc;
	int from_page, to_page;
	BOOL f_gb;
	char tmp_buf[256];
	RECT bx;
	RECT ax;

	if(mode == 1 || (!mode && tmp_cutedge == NULL)){
		if(tmp_cutedge != NULL)
			CutEdge(-1);
		tmp_cutedge = MareaPara("y OX OY", 1);
		c_page = GetCurrentPage();
		total = GetTotalPage();
		if(total < 1)
			return;
		ax.right = ax.bottom = 0;
		ax.left = GetBufXSize();
		ax.top = GetTextYSize();
		f_gs = f_GS;
		f_spc = f_spcolor;
		f_gb = f_gbox;
		f_GS = f_spcolor = 0;	/* cut graphics and color */
		f_gbox = TRUE;
		if(h_hist[RANGE_MARK].id == id_dvi && h_hist[PAGE_MARK].id == id_dvi){
			from_page = h_hist[RANGE_MARK].page;
			to_page = h_hist[PAGE_MARK].page;
			if(from_page > to_page){
				page = to_page;
				to_page = from_page;
				from_page = page;
			}
			if(from_page < 1 || to_page > total)
				goto def;
		}else{
def:		from_page = 1;
			to_page = total;
		}
		for(page = from_page; page <= to_page; page++){
			ChgPage(page);
			ExpandPage0();
			GetBoundingBox((BYTE*)bitmap_buf_pointer->start,
				GetTextXSize(), (GetBufXSize() + 7)/8, GetTextYSize(), 
				&bx);
			if(bx.left < 0)
				continue;
			if(bx.left < ax.left)
				ax.left = bx.left;
			if(bx.right > ax.right)
				ax.right = bx.right;
			if(bx.top < ax.top)
				ax.top = bx.top;
			if(bx.bottom > ax.bottom)
				ax.bottom = bx.bottom;
		}
		if(ax.left < ax.right){
			ax.left   -= edge_space;
			ax.top    -= edge_space;
			ax.right  += edge_space;
			ax.bottom += edge_space;
			sprintf(tmp_buf, 
				"OX=-%ddot/%ddpi OY=-%ddot/%ddpi y=F%ddot/%ddpi:%ddot/%ddpi",
				ax.left, GetXDpi(),
				ax.top, GetYDpi(),
				ax.right - ax.left, GetXDpi(),
				ax.bottom - ax.top, GetYDpi());
			SetPara(tmp_buf, SET_OPTION);
		}
		f_GS = f_gs;
		f_spcolor = f_spc;
		f_gbox = f_gb;
		ChgPage(c_page);
		CheckMenu(ID_CUTEDGE, 1);
	}else if(mode == -1 || (!mode && tmp_cutedge != NULL) ){
		tmp_cutedge = MareaPara(tmp_cutedge, -1);
		CheckMenu(ID_CUTEDGE, 0);
	}
}
