source: trunk/pin/src/conv_ppd.c@ 100

Last change on this file since 100 was 49, checked in by Alex Taylor, 11 years ago

Updates for v0.50:
Moved much of the PPD-import logic into a shared function.
Automatically reimport previously-imported PPDs when updating to a new version of a known PostScript driver.
Ask if the user wants to update the active copy of a driver when the repository version is updated.
Fixed error in locating cupswiz.exe when the desktop object doesn't exist.
Fixed broken update of PRDESC.LST when upgrading to a new version of a known PostScript driver.

File size: 92.4 KB
Line 
1/*DDK*************************************************************************/
2/* */
3/* COPYRIGHT Copyright (C) 1991, 2003 IBM Corporation */
4/* */
5/* The following IBM OS/2 source code is provided to you solely for */
6/* the purpose of assisting you in your development of OS/2 device */
7/* drivers. You may use this code in accordance with the IBM License */
8/* Agreement provided in the IBM Developer Connection Device Driver */
9/* Source Kit for OS/2. This Copyright statement may not be removed. */
10/* */
11/*****************************************************************************/
12/****************************************************************************/
13/* */
14/* */
15/* */
16/* */
17/* */
18/****************************************************************************/
19
20// need full audit!
21// must eliminate RepWarning and RepError
22// declare all internal functions and variables static
23// remove outdated comments and code
24
25/**************************************************************************
26 *
27 * SOURCE FILE NAME = PPD2BIN.C
28 *
29 * DESCRIPTIVE NAME = PPD Formatter
30 *
31 * VERSION = V2.0
32 *
33 * DATE
34 *
35 * DESCRIPTION Parses a PPD files and puts the information in an
36 * output file
37 *
38 *
39 * FUNCTIONS
40 * AmbFilename
41 * atoRound
42 * RepWarning
43 * RepError
44 * SkipNumber
45 * SkipBlank
46 * MovePast
47 * CopyString
48 * CopyInQuote
49 * Openppd
50 * ScanParam
51 * ScanProcedure
52 * AddExtension
53 * FreeAll
54 * RemoveExtension
55 * GetArgs
56 * SaveCommand
57 * SaveProcedure
58 * SaveString
59 * FormPpd
60 * bld_compare
61 * CntInpFiles
62 * WriteRCFile
63 * main
64 *
65 *
66 * NOTES Uses the following format for output file:
67 * The output file consists of following segments:
68 *
69 * 1. Signature
70 * 2. Printer directory segment
71 * 3. One or more printer information segments
72 *
73 * Signature has got the following structure:
74 * Identifying name 40 bytes,
75 * Total no of entries in dir 2 bytes,
76 * Present no of entries in dir 2 bytes,
77 * free 4 bytes.
78 *
79 * Each entry in Printer directory segment has got the
80 * following structure:
81 * Printer name 40 bytes,
82 * Offset of printer segment 4 bytes,
83 * free 4 bytes.
84 *
85 * Each printer information segment has got the structure
86 * stored in format DESPPD. Towards the end of printer info
87 * segment lies the list buffer of length specified by the
88 * first two bytes of DESPPD structure. The buffer contains
89 * various command string lists and dimension lists.
90 *
91 * STRUCTURES
92 *
93 * EXTERNAL REFERENCES
94 *
95 * EXTERNAL FUNCTIONS
96 *
97*/
98//#define INCL_GENPLIB_LAYOUT
99#include <os2.h>
100#include <stdio.h>
101#include <stdlib.h>
102#include <string.h>
103#include <ctype.h>
104#ifndef __KLIBC__
105#include <builtin.h>
106#else
107typedef INT *PINT;
108#define strcmpi strcmp
109#endif
110
111//#include <genplib.h>
112#include "ppd2bin.h"
113//#include "ppdialog.h"
114#include "struct.h"
115#include "fontres.h"
116// #define IBUFFSIZE 2048
117#define IBUFFSIZE (1024 * 35) // upped from 11 [wgs]
118#define MAX_ESC_STR_LEN 256L
119#define COMPRESS TRUE
120#define NOCOMPRESS FALSE
121
122#define CSTR_NORMAL 0
123#define CSTR_INCLUDE_SLASH 1
124#define CSTR_HEX2CHAR 2
125#define CSTR_EXCLUDE_DQUOTE 4
126
127/**************************************************************************
128* The headers #def INT as int. Just following this, there is a #define int SHORT
129* This will cause trouble with using PINTs since it expects a 32 bit value
130* to be pointed to. And that definintion will not be affected by the #define int SHORT
131* To avoid the problem, I undef INT and the use typedef to reassign it.
132* [wgs] 1/17/98
133***********************************************************************/
134#ifdef INT
135#undef INT
136typedef int INT;
137#endif
138
139#define int SHORT
140#define unsigned USHORT
141
142int SkipBlank(char *);
143
144//FILE *ppdOut;
145//BOOL fWriteWords = FALSE;
146long test_prefix = 0x12345678;
147//FILE *fhOut = NULL;
148
149typedef struct
150{
151 FILE *fhFile;
152 long lFileLen;
153 long lCurPos;
154 char *pbBuffer;
155} FILEBUFFER, *PFILEBUFFER;
156
157FILEBUFFER fbIn;
158
159
160long test_post = 0x12345678;
161char abBuffin[IBUFFSIZE]; /* buffer required for reading input */
162/* the following appears only to be used in processing the current file and not stored */
163/* [wgs] and since the input file is might be over 64k(esp. the hp8000_6.ppd) */
164struct
165{
166 long usFileStart;
167 long usFileEnd;
168} UIFileGroup;
169
170char acDefFont[] = "Courier";
171int cbBuffout = 0; /* number of bytes filled in output
172 buffer */
173DESPPD desPpd; /* printer descriptor segments */
174
175
176//char *pbDirBuffer; /* pointer to directory buffer tobe
177// allocated */
178PBYTE pbItemsBuffer; /* pointer to items */
179// static char pbPrBuffer[1024 * 4];
180static char pbPrBuffer[ IBUFFSIZE ];
181USHORT USBlockHeader[ 150 ]; // www.fcuk.lv
182
183BOOL BUI = FALSE;
184
185#define MAX_FORM_SIZE 127
186SHORT sFormCount;
187PCH pFormTable[64]; /* allow 64 forms */
188
189UINT nErrorLogLevel=2;
190//
191// log levels:
192// 5 : very quiet
193// 4 : errors
194// 3 : serious warning
195// 2 : warnings
196// 1 : predictable and handled quirks
197// 0 : log entrance and exit from function
198// log how many times function is called
199//
200
201/*
202** D74609
203*/
204#define TRUNCATE_FLOAT (float) 0.0
205#define ROUND_FLOAT (float) 0.9999
206
207int MovePast( char *, char );
208VOID roundImgAreaVals(int *, float, CHAR );
209
210BOOL VerifyPPDLineSize( PCHAR );
211BOOL BErrorWasDisplayed = FALSE;
212
213VOID ProcessUIList( VOID );
214UINT ProcessUIBlock( PUI_LIST, PUI_BLOCK, UINT, PUSHORT );
215int CopyString( char *, char *, int, UINT );
216
217/*** This is a new section for compression
218*/
219#include "ppdtable.h"
220#define HASHSLOTS 251
221
222typedef struct _WORDELEMENT
223{
224 PSZ pszWord; //Pointer to keyword
225 SHORT sIndex; //0 based index plus adjustment
226 SHORT sList; //0 based list
227 struct _WORDELEMENT *pNext;
228} WORDELEMENT, *PWORDELEMENT;
229
230PWORDELEMENT pPSKeyWords;
231PWORDELEMENT aHashTable[ HASHSLOTS ];
232INT iShrinkage; //When the ppb is expanded this is the diff between
233 //compressed and uncompressed size
234
235INT MatchKeywords( PBYTE, PUI_LIST, PBYTE, BOOL );
236PUI_BLOCK QueryBlockFromKeyword( PUI_LIST, PBYTE, PBYTE, PINT );
237PUI_ENTRY QueryEntryFromOption( PBYTE, PUI_BLOCK, PBYTE, PINT );
238VOID ProcessCmdsAsUIs( VOID );
239INT ProcessUIConstraints( VOID );
240INT CopyWord( PCHAR, PCHAR );
241VOID VerifyUICList( VOID );
242PCHAR SearchKeySubst( PCHAR );
243
244BOOL ParsePPDLang( PSZ, PSZ );
245FILE *MRILangFile;
246CHAR MRIPathString[ CCHMAXPATH ];
247
248
249#include "buffers.ch"
250
251#include "p2phash.ch"
252
253#include "p2putil.ch"
254
255
256/***************************************************************************
257 *
258 * FUNCTION NAME = Openppd
259 *
260 * DESCRIPTION = Opens the file specified in read only text mode and
261 * returns True if open successful ,else FALSE. The
262 * file handle is stored in fhIn
263 *
264 * INPUT = szFileName - filename
265 *
266 * OUTPUT = NONE.
267 *
268 * RETURN-NORMAL = NONE.
269 * RETURN-ERROR = NONE.
270 *
271 ************************************************************************* */
272
273BOOL Openppd( char *szFilename )
274{
275//long i; NOTUSED
276
277
278 fbIn.fhFile = fopen( szFilename, "rb" );
279
280
281 if (!fbIn.fhFile)
282 {
283 /*
284 ** Previously, if a file couldn't be found, then the compiler would stop.
285 ** However, confidential OEM PPD files will not be out on the DDK.
286 ** Therefore, change to simply ignore files that aren't found. However,
287 ** do display it for build purposes.
288 */
289// RepWarning( err_cantopen, szFilename );
290 printf( "[INFO: %s - File not found. Ignore and continue.]\n",
291 szFilename );
292 *szFilename = 0;
293 return( FALSE );
294 }
295
296
297 fseek( fbIn.fhFile, 0L, SEEK_END);
298 fbIn.lFileLen = ftell( fbIn.fhFile );
299 fseek( fbIn.fhFile, 0L, SEEK_SET);
300
301 fbIn.pbBuffer = (char *)malloc( fbIn.lFileLen * sizeof( char ) );
302 fread( fbIn.pbBuffer, sizeof( char ), fbIn.lFileLen, fbIn.fhFile );
303
304
305 fbseek(&fbIn, 0L, SEEK_SET);
306// printf( "Converting %s\n", szFilename );
307 return( TRUE );
308}
309
310/***************************************************************************
311 *
312 * FUNCTION NAME = ScanParam
313 *
314 * DESCRIPTION = This routine scans the szSrchstring in the input
315 * file and provides the remaining parameter in the
316 * return buffer provided. If szSrchstring is found
317 * this routine returns TRUE else FALSE.
318 *
319 * INPUT = szSrchstring - search string address
320 *
321 * OUTPUT = pbBufaddress - return buffer address
322 *
323 * RETURN-NORMAL = NONE.
324 * RETURN-ERROR = NONE.
325 *
326 ************************************************************************* */
327
328BOOL ScanParam( char *szSrchstring, char *pbBufreturn )
329{
330 BOOL fIseof, fIsFound;
331
332 INT j = 0, k;
333 INT i;
334 long li, lc;
335 UINT uiStrLen = strlen( szSrchstring );
336
337 long uiCurrFileLoc;
338 INT x;
339
340 fIseof = FALSE;
341
342 /*
343 ** search for parameter till token found or file eof encountered
344 */
345 while (!fIseof)
346 {
347 if ((lc = fbtell(&fbIn)) == -1L)
348 {
349 return( FALSE );
350 }
351
352 /*
353 **
354 */
355 uiCurrFileLoc = fbtell( &fbIn );
356
357 if ((i = fbread(abBuffin,1,IBUFFSIZE,&fbIn)) != IBUFFSIZE)
358 {
359 fIseof = TRUE;
360 }
361
362 /*
363 ** Verify that the line size does not exceed IBUFFSIZE bytes.
364 ** Report an error and skip the command if this exists.
365 */
366 if (VerifyPPDLineSize( abBuffin ) == TRUE)
367 {
368 if (i <= 1)
369 {
370 break;
371 }
372
373 /*
374 ** Ignore the last partially read line
375 */
376 if (!fIseof) /* didn't hit end of file, then don't need do adjust */
377 { /* ignore the partially read line */
378 if (i > 3)
379 i--;
380 for (li = 1;i;li++, i--)
381 {
382 if ((abBuffin[i] == '*') && (abBuffin[i - 1] == '\n'))
383 {
384 break;
385 }
386 } /* for */
387
388 /*
389 ** shift back the current access pointer of the file
390 ** make it point to the beginning of the partially read line
391 */
392 if (li > 1 && li < IBUFFSIZE)
393 {
394 if (fbseek( &fbIn, -(li-1), SEEK_CUR) == -1L) /* oops, something */
395 {
396 return( FALSE );
397 }
398 } /* check for reasonable backup values */
399 } /* if (!fIseof) */
400
401 j = 0;
402 fIsFound = FALSE;
403 while (j < i)
404 {
405 if (!strncmp( abBuffin+j, szSrchstring, uiStrLen ))
406 {
407 /* @COOK */
408 if (isspace( *(abBuffin + j + uiStrLen) ) ||
409 *(abBuffin + j + uiStrLen) == ':')
410 {
411 fIsFound = TRUE;
412 }
413 }
414 k = j;
415
416 for (;;j++)
417 {
418 /*
419 ** Check to see if a comment is on the next line. This will
420 ** prevent a trap if the compiler finds a comment immediately
421 ** following a command line. The compiler won't read the
422 ** comment and possibly exceed buffer space.
423 */
424 if ((abBuffin[j] == 0xA) && (abBuffin[j+1] == 0x2A ||
425 abBuffin[j+1] == '%'))
426 {
427 j++;
428 break;
429 }
430
431 if (j == i)
432 {
433 break;
434 }
435 }
436
437 if (fIsFound)
438 {
439 /*
440 */
441 if (BUI == TRUE)
442 {
443 fbseek( &fbIn, uiCurrFileLoc + k, SEEK_SET );
444 lc = fbtell( &fbIn );
445
446 /*
447 ** Change '1024 * 4' to IBUFFSIZE.
448 */
449// fread( abBuffin, 1, 1024 * 4, fhIn );
450 fbread( abBuffin, 1, IBUFFSIZE, &fbIn );
451 j = MovePast( abBuffin, ' ' );
452 memset( pbBufreturn, 0, IBUFFSIZE );
453 memcpy( pbBufreturn, abBuffin + j, IBUFFSIZE - j );
454 fbseek( &fbIn, lc + 10, SEEK_SET );
455 }
456 else
457 {
458 k += uiStrLen;
459 k += SkipBlank( abBuffin + k );
460
461 if (j >= k)
462 {
463 x = j - k;
464 }
465 else
466 {
467 x = 0;
468 while (abBuffin[ k + x ] != 0x0A)
469 {
470 x++;
471 }
472 }
473
474 memcpy( pbBufreturn, abBuffin + k, x );
475 }
476 break;
477 }
478 }
479
480 /*
481 ** set the access pointer so that in next access the current
482 ** token is not reencountered
483 */
484 if (fIsFound)
485 {
486 fbseek( &fbIn, lc+(long)j, SEEK_SET );
487 break;
488 }
489 }
490 }
491 return( fIsFound );
492} /* ScanParam */
493
494/***************************************************************************
495 *
496 * FUNCTION NAME = ScanProcedure
497 *
498 * DESCRIPTION = This routine scans the szSrchstring in the input
499 * file and provides the remaining parameter in the
500 * return buffer provided. If szSrchstring is found
501 * this routine returns TRUE else FALSE.
502 *
503 * INPUT = szSrchstring - search string address
504 *
505 * OUTPUT = pbBufaddress - return buffer address
506 *
507 * RETURN-NORMAL = NONE.
508 * RETURN-ERROR = NONE.
509 *
510 ************************************************************************* */
511
512BOOL ScanProcedure( char *szSrchstring,char *pbBufreturn )
513{
514 BOOL fIseof, fIsFound;
515 INT i, j, k, iStrlen;
516 long li;
517
518 fIsFound = FALSE;
519 fIseof = FALSE;
520
521 /*
522 ** search for parameter till token found or file eof encountered
523 */
524 while (!fIseof)
525 {
526 if (fbseek( &fbIn, 0L, SEEK_CUR ) == -1L)
527 {
528 return (FALSE);
529 }
530
531 if ((i = fbread( abBuffin, 1, IBUFFSIZE, &fbIn )) != IBUFFSIZE)
532 {
533 fIseof = TRUE;
534 }
535
536 if (i <= 0)
537 {
538 break;
539 }
540
541 /* Ignore the last partially read line */
542 for (li = 1;i;li++, i--)
543 {
544 if ((abBuffin[IBUFFSIZE - li] == 0x2A) &&
545 (abBuffin[IBUFFSIZE - li - 1] == 0xA))
546 {
547 break;
548 }
549 }
550
551 i--;
552
553 /* shift back the current access pointer of the file */
554 if (li > 1 && li < IBUFFSIZE)
555 {
556 if (fbseek( &fbIn, -li, SEEK_CUR ) == -1L)
557 {
558 return (FALSE);
559 }
560 }
561
562 j = 0;
563 fIsFound = FALSE;
564 iStrlen = 0;
565
566 while (*(szSrchstring + iStrlen) != '\0')
567 {
568 iStrlen++;
569 }
570
571 while (j < i)
572 {
573 if (!strncmp(abBuffin+j, szSrchstring, iStrlen))
574 {
575 if (*(abBuffin+j+iStrlen) == ' ' || *(abBuffin+j+iStrlen) == ':')
576 {
577 fIsFound = TRUE;
578 }
579 }
580 k = j;
581
582 for (;;j++)
583 {
584 if ((abBuffin[j] == 0xA) && (abBuffin[j+1] == 0x2A))
585 {
586 j++;
587 break;
588 }
589 if (j == i)
590 {
591 break;
592 }
593 }
594
595 if (fIsFound)
596 {
597 /*
598 ** now reset the file to start of where the token has been
599 ** encountered and read a large block so that entire procedure
600 ** might be covered.
601 */
602 if (fbseek( &fbIn, (long) - (i - k), SEEK_CUR) == -1L)
603 {
604 return( FALSE );
605 }
606
607 if ((i = fbread( abBuffin, 1, IBUFFSIZE, &fbIn)) <= 0)
608 {
609 return( FALSE );
610 }
611 k = iStrlen;
612 k += MovePast( abBuffin+k, '"' );
613 j = 0;
614
615 while (abBuffin[k] != '"' && k < i)
616 {
617 if (abBuffin[k] != '\r')
618 {
619 *(pbBufreturn + 2 + j++) = abBuffin[k++];
620 }
621 else
622 {
623 k++;
624 }
625 }
626 *(pbBufreturn+2+j) = '\0';
627 *(int *)pbBufreturn = (1+j);
628 return (TRUE);
629 }
630 }
631 }
632 return (fIsFound);
633}
634
635
636/***************************************************************************
637 *
638 * FUNCTION NAME = SaveCommand
639 *
640 * DESCRIPTION = This routine scans the parameter buffer and saves
641 * the command within quotes in pbItemsBuffer .This
642 * routine is written to save code.
643 *
644 * INPUT = szString - pointer to string to be searched
645 *
646 * OUTPUT = piOffset - pointer to variable where offset is to be
647 * stored
648 *
649 * RETURN-NORMAL = NONE.
650 * RETURN-ERROR = NONE.
651 *
652 ************************************************************************* */
653
654VOID SaveCommand(char *szString,short *piOffset,BOOL CompressFlag)
655{
656 int i, j;
657 BOOL fPrnName;
658
659 fbseek( &fbIn, (long)0, SEEK_SET );
660
661 if (ScanParam(szString, pbPrBuffer))
662 {
663 /*
664 ** skip the " character
665 */
666 i = MovePast( pbPrBuffer, '"' );
667 fPrnName = (strcmp( szString, "*NickName" ) == 0) |
668 (strcmp( szString, "*ShortNickName" ) == 0);
669 *piOffset = cbBuffout;
670
671 /* The data within quotes is NULL */
672 if (pbPrBuffer[i-1] == '"' && pbPrBuffer[i-2] == '"')
673 {
674 *piOffset = 0;
675 return;
676 }
677
678 /*
679 ** copies the string delimited by quote with ist byte as length.
680 */
681 j = CopyInQuote( pbItemsBuffer + cbBuffout, pbPrBuffer + i, fPrnName,
682 CompressFlag);
683 cbBuffout += j;
684 }
685 else
686 {
687 /*
688 ** Null pointer
689 */
690 *piOffset = -1;
691 }
692}
693
694/***************************************************************************
695 *
696 * FUNCTION NAME = SaveProcedure
697 *
698 * DESCRIPTION = This routine scans the parameter buffer and saves
699 * the procedure within quotes in pbItemsBuffer .This
700 * routine is written to save code.
701 *
702 * INPUT = szString - pointer to string to be searched.
703 *
704 * OUTPUT = piOffset - pointer to variable where offset is to be
705 * stored.
706 *
707 * RETURN-NORMAL = NONE.
708 * RETURN-ERROR = NONE.
709 *
710 ************************************************************************* */
711
712VOID SaveProcedure( char *szString, short *piOffset )
713{
714 int j;
715
716 fbseek( &fbIn, (long) 0, SEEK_SET );
717
718 if (ScanProcedure( szString, pbItemsBuffer + cbBuffout ))
719 {
720 *piOffset = cbBuffout;
721 j = *(int *)(pbItemsBuffer + cbBuffout );
722
723 /*
724 ** 2 bytes extra to take care of length
725 */
726 cbBuffout += ( j + 2 );
727 }
728 else
729 {
730 /*
731 ** Null pointer
732 */
733 *piOffset = -1;
734 }
735}
736
737/***************************************************************************
738 *
739 * FUNCTION NAME = SaveString
740 *
741 * DESCRIPTION = This routine scans the parameter buffer and saves
742 * the keyword following colon in pbItemsBuffer . This
743 * routine is written to save code/
744 *
745 * INPUT = szString - pointer to string to be searched.
746 *
747 * OUTPUT = piOffset - pointer to variable where offset is to be
748 * stored.
749 *
750 * RETURN-NORMAL = NONE.
751 * RETURN-ERROR = NONE.
752 *
753 ************************************************************************* */
754
755VOID SaveString( char *szString, short *piOffset )
756{
757 int i, j;
758
759 fbseek( &fbIn, (long) 0, SEEK_SET );
760
761 if (ScanParam( szString, pbPrBuffer ))
762 {
763 /*
764 ** skip the " character
765 */
766
767 i = MovePast( pbPrBuffer, ':' );
768 *piOffset = cbBuffout;
769 i += SkipBlank(pbPrBuffer+i );
770
771 /*
772 ** copies the string delimited by a blank with ist byte as length.
773 ** Strings are not null terminated
774 */
775 if (strncmp( pbPrBuffer + i, "Unknown", 7 ))
776 {
777
778 j = CopyString( pbItemsBuffer + cbBuffout,
779 pbPrBuffer + i,
780 80,
781 CSTR_NORMAL );
782 cbBuffout += j;
783 }
784 else
785 {
786 *piOffset = -1;
787 }
788 }
789 else
790 {
791 /*
792 ** Null pointer
793 */
794 *piOffset = -1;
795 }
796}
797
798/*****************************************************************************\
799**
800** FUNCTION TrimString
801**
802** Delete trailing whitespace of string
803**
804\*****************************************************************************/
805
806static
807void TrimString ( PSZ str )
808{
809 if( str == NULL || *str == 0 ) return;
810
811 while( (*str) !=0 ) str++; // find the end of the string
812 str--; // get to last character (step over 0)
813 while( isblank(*str) ) str--; // see if the character is blank, keep backstepping
814 str++; // step over non-blank, get to last blank
815 *str = 0; // cut the whitespace off
816}
817
818/*****************************************************************************\
819**
820** FUNCTION NameToIndex
821**
822** Will look up form in table and put index in PPB. Adds form if not there
823**
824\*****************************************************************************/
825
826SHORT NameToIndex( VOID )
827{
828 SHORT i;
829 SHORT sNameLen;
830 CHAR acFormName[MAX_FORM_SIZE+1]; /* Buffer for found form name */
831 PCH pFormName;
832
833 /*
834 */
835
836 sNameLen = CopyString( acFormName,
837 pbPrBuffer,
838 MAX_FORM_SIZE,
839 CSTR_NORMAL );
840 acFormName[MAX_PSIZE-1] = '\0'; /* For now limit to 64 char */
841 pFormName = acFormName;
842
843
844 /* find form in table */
845
846 for ( i = 0; i < sFormCount; i++ )
847 {
848 if ( !strcmp( pFormName, pFormTable[i] ) )
849 break ; /* Found - stop loop */
850 }
851
852 /* Warn if about to overflow table */
853 if ( sFormCount == 63 )
854 {
855 printf( "[WARNING: Too many form names]\n" );
856 i = 0; /* set to first form */
857 }
858
859 if ( i >= sFormCount )
860 { /* Couldn't find it so add to table */
861 pFormTable[ sFormCount ] = (PCH)malloc( strlen( pFormName ) + 1 );
862 strcpy( pFormTable[ sFormCount ], pFormName );
863 i = sFormCount++;
864 }
865
866 *(PSHORT)(pbItemsBuffer+cbBuffout) = i;
867
868 cbBuffout += sizeof(SHORT);
869
870 return sNameLen;
871}
872
873/*****************************************************************************\
874**
875** FUNCTION ProcessFormTable
876**
877** Writes out the form table and index
878**
879\*****************************************************************************/
880
881VOID ProcessFormTable( VOID )
882{
883 SHORT i;
884 LONG lIndexTable[64];
885//PUI_BLOCK pBlock;NOTUSED
886//INT iNumOfPages; NOTUSED
887//INT iNumOfPageRegions; NOTUSED
888
889#if 0
890///*
891//** Do a sanity check
892//*/
893//if ( desPpd.desPage.iCmpgpairs != sFormCount ||
894// desPpd.desPage.iDmpgpairs != sFormCount ||
895// desPpd.desPage.iImgpgpairs != sFormCount )
896//{
897// printf( "WARNING - Mismatched forms counts: PageRegion %d, PaperDim %d, "
898// "ImageableArea %d, Total Count %d\n", desPpd.desPage.iCmpgpairs,
899// desPpd.desPage.iDmpgpairs, desPpd.desPage.iImgpgpairs, sFormCount );
900//}
901#endif
902
903 desPpd.desForms.usFormCount = sFormCount; /* store form count */
904 desPpd.desForms.ofsFormTable = cbBuffout; /* store start of form table */
905
906 /* Write out the table - it's regular null term strings */
907 for ( i = 0; i < sFormCount; i++ )
908 {
909 PCHAR p;
910 INT j;
911 INT iLen;
912
913 lIndexTable[i] = cbBuffout; /* Keep track of where each form goes */
914// strcpy( pbItemsBuffer + cbBuffout, pFormTable[ i ] );
915 p = pFormTable[i];
916 iLen = strlen( p );
917 *(p + iLen) = '"'; //Replace null term with quote
918 j = CopyInQuote( pbItemsBuffer + cbBuffout, p, FALSE, COMPRESS);
919 iShrinkage += ( iLen + 1 ) - j; //J includes null term
920
921
922 free( pFormTable[ i ] );
923// cbBuffout += strlen( pFormTable[ i ] ) + 1;
924 cbBuffout += j;
925 }
926
927 desPpd.desForms.ofsFormIndex = cbBuffout; /* store start of index table */
928
929 for ( i = 0; i < sFormCount; i++ )
930 {
931 *(PLONG)(pbItemsBuffer+cbBuffout) = lIndexTable[ i ];
932 cbBuffout += sizeof(LONG);
933 }
934
935}
936
937/*****************************************************************************\
938**
939** FUNCTION DoDefaultForm
940**
941** Converts the default string found by the old method to the index of a form.
942** This means that desPpd.desPage.ofsDfpgsz is NOT an offset but an index value
943**
944\*****************************************************************************/
945
946VOID DoDefaultForm( VOID )
947{
948 PBYTE ptr;
949 PBYTE pImageableArea;
950 SHORT sLen;
951 SHORT i;
952 SHORT j;
953 PCH pchSlash;
954 SHORT sFirstForm;
955
956
957 /* if value -1 no default form so use the first form */
958 if ( desPpd.desPage.ofsDfpgsz == -1 )
959 {
960 desPpd.desPage.ofsDfpgsz = 0;
961 printf( "[INFO: No default form]\n" );
962 return;
963 }
964
965 ptr = pbItemsBuffer + desPpd.desPage.ofsDfpgsz;
966 sLen = strlen( ptr );
967
968 /* Point to imageable area */
969 pImageableArea = pbItemsBuffer + desPpd.desPage.ofsImgblPgsz;
970 sFirstForm = *((PSHORT)pImageableArea);
971
972 for ( j = 0; j < desPpd.desPage.iImgpgpairs; j++ )
973 {
974
975 i = *((PSHORT)pImageableArea);
976 pImageableArea += sizeof( SHORT ) * 5;
977
978 /*
979 ** If Xlate string, block it by temp replacing slash with zero
980 */
981 if ( ( pchSlash = strchr( pFormTable[i], '/' ) ) != 0 )
982 {
983 *pchSlash = 0;
984 }
985
986 if ( !strcmp( (PCH)ptr, pFormTable[i] ) )
987 {
988 if ( pchSlash )
989 {
990 *pchSlash = '/';
991 }
992 break;
993 }
994 if ( pchSlash )
995 {
996 *pchSlash = '/';
997 }
998 }
999
1000 if ( j >= desPpd.desPage.iImgpgpairs ) /* Not found, make it zero */
1001 {
1002 i = sFirstForm;
1003 printf( "[INFO: Default form is %s]\n", ptr );
1004 }
1005
1006 desPpd.desPage.ofsDfpgsz = i;
1007
1008 cbBuffout -= sLen + 1; /* Erase the name */
1009
1010 return;
1011}
1012
1013
1014/***************************************************************************
1015 *
1016 * FUNCTION NAME = FormPpd
1017 *
1018 * DESCRIPTION = To form a binary output segment out of ppd file.
1019 * Returns false if any error encountered in input
1020 * file format else returns True.
1021 *
1022 * INPUT = NONE.
1023 * OUTPUT = NONE.
1024 *
1025 * RETURN-NORMAL = NONE.
1026 * RETURN-ERROR = NONE.
1027 *
1028 ************************************************************************* */
1029
1030BOOL FormPpd(void)
1031{
1032 #define NOT_SELECTED -1
1033 /*
1034 ** D74609
1035 */
1036/* register int i; */
1037 int i;
1038 int j, k;
1039 char *p, *q;
1040 char *px;
1041 char scratch[64 + 1];
1042//int iResType; /* QMS fix */
1043
1044 PUI_BLOCK pBlock;
1045 PUI_BLOCK pTempBlock;
1046 INT y;
1047
1048 /*
1049 ** Zero out structure
1050 */
1051
1052 p = (char *) desPpd.stUIList.pBlockList;
1053 q = (char *) desPpd.stUICList.puicBlockList;
1054 memset( &desPpd, 0, sizeof( desPpd ) );
1055 desPpd.stUIList.pBlockList = (PUI_BLOCK) p;
1056 desPpd.stUICList.puicBlockList = (PUIC_BLOCK) q;
1057 memset( desPpd.stUIList.pBlockList, 0, 4000 );
1058
1059 desPpd.desItems.ofsPswrd = -1;
1060
1061 /*
1062 */
1063 /*
1064 ** For v4.2 PPDs, JCLBegin and JCLToPSInterpreter replaces
1065 ** InitPostScriptMode.
1066 */
1067 SaveCommand( szSearch[initstring], (short *) &desPpd.desItems.ofsInitString,
1068 COMPRESS);
1069 if (desPpd.desItems.ofsInitString == -1)
1070 {
1071 SaveCommand (szSearch[ JCLBegin ], (short *) &desPpd.desItems.ofsInitString,
1072 COMPRESS);
1073 /*
1074 ** Add a separate offset for the JCL to PS interpreter command. Do not
1075 ** append it to the *JCLBegin command. This is needed so if JCLResolution
1076 ** is used, this command converts the device back to Postscript.
1077 ** JCLResolution must be inserted between the JCLBegin and the
1078 ** JCL-to-PS commands.
1079 */
1080 SaveCommand( szSearch[ JCLToPSInterpreter ],
1081 (short *) &desPpd.desItems.ofsJCLToPS, COMPRESS);
1082 }
1083
1084 /*
1085 */
1086 /*
1087 ** For v4.2PPDs, JCLEnd is the command that replaces TermPostScriptMode.
1088 */
1089 SaveCommand( szSearch[termstring], (short *) &desPpd.desItems.ofsTermString,
1090 COMPRESS);
1091 if (desPpd.desItems.ofsTermString == -1)
1092 {
1093 SaveCommand( szSearch[ JCLEnd ], (short *) &desPpd.desItems.ofsTermString,
1094 COMPRESS);
1095 }
1096
1097 /*
1098 ** scan and read the throughput parameter
1099 */
1100 fbseek( &fbIn, (long)0, SEEK_SET );
1101
1102 if (ScanParam( szSearch[throughput], pbPrBuffer ))
1103 {
1104 /*
1105 ** skip the " character
1106 */
1107
1108 i = MovePast( pbPrBuffer, '"' );
1109 desPpd.desItems.iPpm = (short) atoi( pbPrBuffer + i );
1110 }
1111 else
1112 {
1113 /*
1114 ** Null value
1115 */
1116 desPpd.desItems.iPpm = -1;
1117 }
1118
1119 /*
1120 ** scan and read the printer memory parameter
1121 */
1122 fbseek( &fbIn, (long)0, SEEK_SET );
1123
1124 if (ScanParam( szSearch[freevm], pbPrBuffer ))
1125 {
1126 /*
1127 ** skip the " character
1128 */
1129 i = MovePast( pbPrBuffer, '"' );
1130 desPpd.desItems.lFreeVM = atol( pbPrBuffer + i );
1131 }
1132 else
1133 {
1134 /*
1135 ** Null value
1136 */
1137 desPpd.desItems.lFreeVM = (long) -1;
1138 }
1139
1140 /*
1141 ** scan and read the PCFileName
1142 */
1143 desPpd.desItems.ofsPCFileName = cbBuffout;
1144 SaveCommand( szSearch[PCFileName], (short *) &desPpd.desItems.ofsPCFileName,
1145 NOCOMPRESS);
1146
1147 /*
1148 ** scan and read printer type classified under product name
1149 */
1150
1151 desPpd.desItems.ofsPrType = cbBuffout;
1152 desPpd.desItems.ofsPrType = -1;
1153
1154 /*
1155 ** scan and read printer name
1156 ** Try ShortNickName first
1157 */
1158 desPpd.desItems.ofsPrName = cbBuffout;
1159 SaveCommand( szSearch[shortnickname], (short *) &desPpd.desItems.ofsPrName,
1160 NOCOMPRESS);
1161
1162 if ( desPpd.desItems.ofsPrName == -1 )
1163 {
1164 /*
1165 ** scan and read printer name
1166 ** Use NickName
1167 */
1168 desPpd.desItems.ofsPrName = cbBuffout;
1169 SaveCommand( szSearch[printername], (short *) &desPpd.desItems.ofsPrName,
1170 NOCOMPRESS);
1171 }
1172
1173 TrimString( pbItemsBuffer + desPpd.desItems.ofsPrName );
1174
1175 /*
1176 ** Make sure name is not too long
1177 */
1178 /*
1179 */
1180 if (strlen( pbItemsBuffer + desPpd.desItems.ofsPrName ) > NAME_LEN - 1)
1181 {
1182 printf( "[WARNING: Nickname too long, truncated]\n" );
1183 *(pbItemsBuffer + desPpd.desItems.ofsPrName + NAME_LEN - 1) = 0; // terminate the string
1184 }
1185
1186 /*
1187 ** Move the Default resolution processing after the standard resolution
1188 ** processing. If no default resolution is provided, assign the default
1189 ** to the first resolution found.
1190 */
1191 /*
1192 ** scan and read default resolution
1193 */
1194 fbseek( &fbIn, (long)0, SEEK_SET );
1195
1196 if (ScanParam( szSearch[defaultres], pbPrBuffer ))
1197 {
1198 /*
1199 ** skip the : character
1200 */
1201 i = MovePast( pbPrBuffer, ':' );
1202 desPpd.desItems.iResDpi = (short) atoi( pbPrBuffer + i );
1203 }
1204
1205 /* If no default found try default JCL */
1206 if ( desPpd.desItems.iResDpi == 0 )
1207 {
1208 fbseek( &fbIn, (long)0, SEEK_SET );
1209 if (ScanParam( szSearch[defaultJCLRes], pbPrBuffer ))
1210 {
1211 i = MovePast( pbPrBuffer, ':' );
1212 desPpd.desItems.iResDpi = (short) atoi( pbPrBuffer + i );
1213 }
1214 }
1215
1216 // beef up resolution
1217 if (desPpd.desItems.iResDpi == 0)
1218 {
1219#if 0
1220 desPpd.desItems.iResDpi = 300;
1221#else
1222 desPpd.desItems.iResDpi = 1440; // workaround for WordPro printing problem
1223#endif
1224 }
1225
1226 /*
1227 ** scan and read screen frequency
1228 */
1229 fbseek( &fbIn, (long)0, SEEK_SET );
1230
1231 if (ScanParam(szSearch[screenfreq], pbPrBuffer))
1232 {
1233 /*
1234 ** skip the : character
1235 */
1236
1237 i = MovePast( pbPrBuffer, '"' );
1238 desPpd.desItems.lScrFreq = (long)(atof( pbPrBuffer + i) * 100.00 );
1239 }
1240 else
1241 {
1242 /*
1243 ** Null value
1244 */
1245 desPpd.desItems.lScrFreq = -1L;
1246 }
1247
1248 /*
1249 ** To read the flag that indicates whether the device supports
1250 ** colour or not.
1251 */
1252 fbseek( &fbIn, (long)0, SEEK_SET );
1253
1254 if (ScanParam( szSearch[colordevice], pbPrBuffer ))
1255 {
1256 /*
1257 ** skip the " character
1258 */
1259 i = MovePast( pbPrBuffer, ':' );
1260 i += SkipBlank( pbPrBuffer + i );
1261
1262 if (!strnicmp("TRUE", pbPrBuffer+i, 4))
1263 {
1264 desPpd.desItems.fIsColorDevice = TRUE;
1265 }
1266 else
1267 {
1268 desPpd.desItems.fIsColorDevice = NONE;
1269 }
1270 }
1271 else
1272 {
1273 desPpd.desItems.fIsColorDevice = NONE;
1274 }
1275
1276 /*
1277 ** To read the True or False value indicating whether the Postscript
1278 ** device has a built in file system.
1279 */
1280 fbseek( &fbIn, (long)0, SEEK_SET );
1281
1282 if (ScanParam( szSearch[filesystem], pbPrBuffer ))
1283 {
1284 /*
1285 ** skip the " character
1286 */
1287 i = MovePast( pbPrBuffer, ':' );
1288 i += SkipBlank(pbPrBuffer + i );
1289
1290 if (!strnicmp( "TRUE", pbPrBuffer + i, 4 ))
1291 {
1292 desPpd.desItems.fIsFileSystem = TRUE;
1293 }
1294 else
1295 {
1296 desPpd.desItems.fIsFileSystem = FALSE;
1297 }
1298 }
1299 else
1300 {
1301 desPpd.desItems.fIsFileSystem = FALSE;
1302 }
1303
1304 /*
1305 ** To read the Postscript sequence that will perform a soft
1306 ** restart of the printer.
1307 */
1308 desPpd.desItems.ofsReset = -1;
1309
1310 /*
1311 ** Read the appropriate postscript sequence to exit the job server loop
1312 */
1313 desPpd.desItems.ofsExitserver = -1;
1314
1315 /*
1316 ** Read the halftone screen angle
1317 */
1318 fbseek( &fbIn, (long)0, SEEK_SET );
1319
1320 if (ScanParam( szSearch[screenangle], pbPrBuffer ))
1321 {
1322 /*
1323 ** skip the : character
1324 */
1325 i = MovePast( pbPrBuffer, '"' );
1326 desPpd.desItems.iScreenAngle = (long)(atof( pbPrBuffer + i) * 100.0 );
1327 }
1328 else
1329 {
1330 /*
1331 ** Null value
1332 */
1333 desPpd.desItems.iScreenAngle = -1L;
1334 }
1335
1336 /*
1337 ** Read the values indicating whether the device supports
1338 ** infinitely variable paper sizes
1339 */
1340
1341
1342 /* */
1343
1344 desPpd.desPage.ofsCustomPageSize = -1;
1345 //
1346 fbseek( &fbIn, (long)0, SEEK_SET );
1347 if (ScanParam( szSearch[CustomPageSize], pbPrBuffer ))
1348 {
1349 if (!strnicmp( "TRUE", pbPrBuffer, strlen("TRUE") ))
1350 {
1351 desPpd.desPage.ofsCustomPageSize = cbBuffout;
1352 i = MovePast( pbPrBuffer, '"' );
1353 j = CopyInQuote( pbItemsBuffer+cbBuffout, pbPrBuffer+i, FALSE, COMPRESS );
1354 cbBuffout += j;
1355 }
1356 }
1357 //
1358 ///
1359 desPpd.desPage.iCustomPageSizeMinWidth = NOT_SELECTED;
1360 desPpd.desPage.iCustomPageSizeMaxWidth = NOT_SELECTED;
1361 desPpd.desPage.iCustomPageSizeMinHeight = NOT_SELECTED;
1362 desPpd.desPage.iCustomPageSizeMaxHeight = NOT_SELECTED;
1363 ///
1364 fbseek( &fbIn, (long)0, SEEK_SET );
1365 while(ScanParam(szSearch[ParamCustomPageSize],pbPrBuffer))
1366 {
1367 if(!strnicmp("Width",pbPrBuffer,strlen("Width")))
1368 {
1369 if(strstr(pbPrBuffer,"points") != NULL)
1370 {
1371 px = strstr(pbPrBuffer,"points") + strlen("points");
1372 i = SkipBlank(px);
1373 px += i;
1374 desPpd.desPage.iCustomPageSizeMinWidth = (SHORT)atoi(px);
1375 i = MovePast( px, ' ' );
1376 px += i;
1377 desPpd.desPage.iCustomPageSizeMaxWidth = (SHORT)atoi(px);
1378 }
1379 }
1380 if(!strnicmp("Height",pbPrBuffer,strlen("Height")))
1381 {
1382 if(strstr(pbPrBuffer,"points") != NULL)
1383 {
1384 px = strstr(pbPrBuffer,"points") + strlen("points");
1385 i = SkipBlank(px);
1386 px += i;
1387 desPpd.desPage.iCustomPageSizeMinHeight = (SHORT)atoi(px); // ALT
1388 i = MovePast( px, ' ' );
1389 px += i;
1390 desPpd.desPage.iCustomPageSizeMaxHeight = (SHORT)atoi(px); // ALT
1391 }
1392 }
1393 if(desPpd.desPage.iCustomPageSizeMinWidth != NOT_SELECTED &&
1394 desPpd.desPage.iCustomPageSizeMinHeight != NOT_SELECTED )break;
1395 }
1396 if (
1397 desPpd.desPage.ofsCustomPageSize != NOT_SELECTED &&
1398 desPpd.desPage.iCustomPageSizeMinWidth != NOT_SELECTED &&
1399 desPpd.desPage.iCustomPageSizeMaxWidth != NOT_SELECTED &&
1400 desPpd.desPage.iCustomPageSizeMinHeight != NOT_SELECTED &&
1401 desPpd.desPage.iCustomPageSizeMaxHeight != NOT_SELECTED
1402 )
1403 {
1404 desPpd.desPage.fIsVariablePaper = FALSE;
1405 fbseek( &fbIn, (long)0, SEEK_SET );
1406
1407 if (ScanParam( szSearch[variablepaper], pbPrBuffer ))
1408 {
1409 /*
1410 ** skip the " character
1411 */
1412 i = MovePast( pbPrBuffer, ':' );
1413 i += SkipBlank( pbPrBuffer + i );
1414
1415 if (!strnicmp( "TRUE", pbPrBuffer + i, 4 ))
1416 {
1417 desPpd.desPage.fIsVariablePaper = TRUE;
1418 }
1419 else
1420 {
1421 desPpd.desPage.fIsVariablePaper = FALSE;
1422 }
1423 }
1424 else
1425 {
1426 desPpd.desPage.fIsVariablePaper = TRUE;
1427 }
1428 }
1429 else
1430 {
1431 desPpd.desPage.fIsVariablePaper = FALSE;
1432 }
1433
1434 fbseek( &fbIn, (long)0, SEEK_SET );
1435
1436
1437
1438
1439
1440
1441 /*
1442 ** Read the default imageable area paper type .
1443 */
1444 desPpd.desPage.ofsDefimagearea = -1;
1445
1446 /*
1447 ** Read the keyword for the Default paper dimension.
1448 ** This value should always be letter
1449 */
1450 desPpd.desPage.ofsDefpaperdim = -1;
1451
1452 /*
1453 ** This gives the font name which is the default font provided by
1454 ** findfont if the requested font is not available
1455 */
1456 SaveString( szSearch[defaultfont], (short *)&desPpd.desFonts.ofsDeffont );
1457
1458 /*
1459 ** If no default font provided make it Courier
1460 */
1461 if (desPpd.desFonts.ofsDeffont == -1)
1462 {
1463 /*
1464 ** Copy the default font (no ending null)
1465 */
1466 desPpd.desFonts.ofsDeffont = cbBuffout;
1467 *(pbItemsBuffer + cbBuffout) = sizeof( acDefFont ) - 1;
1468 cbBuffout++;
1469
1470 for (i = 0; i < sizeof( acDefFont )-1; i++, cbBuffout++)
1471 {
1472 *(pbItemsBuffer + cbBuffout) = acDefFont[i];
1473 }
1474 }
1475
1476 /*
1477 ** Read the keyword for the default output order which can be normal
1478 ** or reverse
1479 */
1480
1481 fbseek( &fbIn, (long)0, SEEK_SET );
1482
1483 if (ScanParam( szSearch[defoutputorder], pbPrBuffer))
1484 {
1485 /*
1486 ** skip the " character
1487 */
1488 i = MovePast( pbPrBuffer, ':' );
1489 i += SkipBlank( pbPrBuffer + i );
1490
1491 if (!strnicmp( "NORMAL", pbPrBuffer + i, 6))
1492 {
1493 desPpd.desOutbins.fIsDefoutorder = NORMAL;
1494 }
1495 else
1496 {
1497 desPpd.desOutbins.fIsDefoutorder = REVERSE;
1498 }
1499 }
1500 else
1501 {
1502 desPpd.desOutbins.fIsDefoutorder = REVERSE;
1503 }
1504
1505 /*
1506 ** Read the invocation strings for selecting normal or
1507 ** reverse output order
1508 */
1509 desPpd.desOutbins.ofsOrdernormal = -1;
1510 desPpd.desOutbins.ofsOrderreverse = -1;
1511 fbseek( &fbIn, (long)0, SEEK_SET );
1512
1513 while (ScanParam( szSearch[outputorder], pbPrBuffer))
1514 {
1515 if (!strnicmp( "NORMAL", pbPrBuffer, 4))
1516 {
1517 desPpd.desOutbins.ofsOrdernormal = cbBuffout;
1518 }
1519 else
1520 {
1521 desPpd.desOutbins.ofsOrderreverse = cbBuffout;
1522 }
1523
1524 /*
1525 ** skip the " character
1526 */
1527 i = MovePast( pbPrBuffer, '"' );
1528
1529 /*
1530 ** copies the string delimited by a blank or quote with ist byte
1531 ** as length. Strings are not null terminated
1532 */
1533 j = CopyInQuote( pbItemsBuffer+cbBuffout, pbPrBuffer+i, FALSE,
1534 COMPRESS );
1535 cbBuffout += j;
1536 }
1537
1538 /*
1539 ** Read the complete procedure of Transfer Normalized & inverse
1540 */
1541 SaveProcedure( szSearch[transfernor], (short *)&desPpd.desItems.ofsTransferNor );
1542 SaveProcedure( szSearch[transferinv], (short *)&desPpd.desItems.ofsTransferInv );
1543
1544 /*
1545 ** Read the invocation strings for various output bins
1546 */
1547 fbseek( &fbIn, (long)0, SEEK_SET );
1548 k = 0;
1549
1550 desPpd.desOutbins.iOutbinpairs = k;
1551 desPpd.desOutbins.ofsCmOutbins = -1;
1552
1553 /*
1554 ** Insert the section of code that searches for the "*LanguageLevel"
1555 ** PostScript command.
1556 */
1557 fbseek( &fbIn, (long)0, SEEK_SET );
1558
1559 if (ScanParam( szSearch[LanguageLevel], pbPrBuffer ))
1560 {
1561 /*
1562 ** Skip past the colon, spaces, and the first quote, until a numeric
1563 ** character is found. The reason for the loop below is, even though
1564 ** the PPD specs require the PS level to be in quotes, this is not the
1565 ** case for all PPDs. Since this compiler cannot assume that the
1566 ** level number is in quotes, it will have to continue to increment
1567 ** the offset until the first numeric character is found.
1568 */
1569 i = 0;
1570 while (*(pbPrBuffer + i) < '0' || *(pbPrBuffer + i) > '9')
1571 {
1572 i++;
1573 }
1574
1575 /*
1576 ** Save the language level offset.
1577 */
1578 desPpd.desItems.usLanguageLevel = atoi( pbPrBuffer + i );
1579 }
1580 else
1581 {
1582 desPpd.desItems.usLanguageLevel = 1;
1583 }
1584 /*
1585 */
1586
1587
1588 fbseek( &fbIn, (long)0, SEEK_SET );
1589 memset( &UIFileGroup, 0, sizeof( UIFileGroup ) );
1590 while (ScanParam( szSearch[ OpenGroup ], pbPrBuffer ))
1591 {
1592 i = MovePast( pbPrBuffer, ' ' );
1593 if (!strnicmp( "InstallableOptions", pbPrBuffer + i, 18))
1594 {
1595 UIFileGroup.usFileStart = fbtell( &fbIn ); /* took out the cast, since it's the same size */
1596
1597 if (ScanParam( szSearch[ CloseGroup ], pbPrBuffer ))
1598 {
1599 UIFileGroup.usFileEnd = fbtell( &fbIn ); /* took out the cast, since it's the same size */
1600 }
1601 }
1602 }
1603 ProcessUIList( );
1604 ProcessCmdsAsUIs( );
1605
1606 /*
1607 ** count of pairs formed
1608 */
1609 k = 0;
1610 desPpd.desPage.ofsDimxyPgsz = cbBuffout;
1611
1612 fbseek( &fbIn, (long)0, SEEK_SET );
1613 if ((pBlock = QueryBlockFromKeyword( &desPpd.stUIList, pbItemsBuffer,
1614 UINAME_PAGESIZE, NULL )) != NULL)
1615 {
1616 while (ScanParam( szSearch[pagesizelist], pbPrBuffer ))
1617 {
1618 y = 0;
1619 i = 0;
1620 while (*(pbPrBuffer + i) != ' ' && *(pbPrBuffer + i) != ':' &&
1621 *(pbPrBuffer + i) != '/')
1622 {
1623 scratch[ y++ ] = *(pbPrBuffer + i++);
1624 }
1625 scratch[ y ] = 0;
1626
1627 pTempBlock = pBlock;
1628 QueryEntryFromOption( (PBYTE) pbItemsBuffer, pTempBlock,
1629 (PBYTE) scratch, (PINT) &y );
1630 *((PSHORT) (pbItemsBuffer + cbBuffout)) = (SHORT) y;
1631 cbBuffout += 2;
1632
1633 /*
1634 ** warn if formname longer than 31
1635 */
1636 if (i > MAX_PSIZE - 1)
1637 {
1638 strncpy( scratch, pbItemsBuffer + cbBuffout - i, i );
1639 scratch[i] = (char) 0;
1640 printf( "[WARNING: %s, Formname > MaxPaperSize (%d)]\n", scratch, i );
1641 }
1642
1643 if ( *(pbPrBuffer + i) == '/' )
1644 {
1645 i += MovePast( pbPrBuffer+i, ':' );
1646 }
1647 /*
1648 ** skip the " character
1649 */
1650 i += MovePast( pbPrBuffer+i, '"' );
1651 j = atoRound( pbPrBuffer + i );
1652
1653 /*
1654 ** copies the x-size into items buffer
1655 */
1656 memcpy( (pbItemsBuffer + cbBuffout), (char *) &j, sizeof( SHORT ) );
1657 cbBuffout += sizeof(SHORT );
1658 i += SkipNumber( pbPrBuffer + i );
1659 j = atoRound( pbPrBuffer + i );
1660
1661 /*
1662 ** copies the y-size into items buffer
1663 */
1664 memcpy( (pbItemsBuffer + cbBuffout), (char *) &j, sizeof( SHORT ) );
1665 cbBuffout += sizeof( SHORT );
1666 k++;
1667 }
1668 desPpd.desPage.iDmpgpairs = k;
1669
1670 /*
1671 ** count of pairs formed
1672 */
1673 fbseek( &fbIn, (long)0, SEEK_SET );
1674 k = 0;
1675 desPpd.desPage.ofsImgblPgsz = cbBuffout;
1676
1677 /*
1678 ** D74609
1679 ** *ImageableArea: value1, value2, value3, value4
1680 ** value1 and value2 must be rounded up.
1681 ** value3 and value4 must be truncated.
1682 */
1683 while (ScanParam( szSearch[imageablearea], pbPrBuffer))
1684 {
1685 CHAR achOldSuffix[ 64 + 1 ];
1686 PCHAR pcSlash;
1687
1688 j = 0;
1689 y = 0;
1690 i = 0;
1691 while (*(pbPrBuffer + i) != ':' && *(pbPrBuffer + i) != '/')
1692 {
1693 scratch[ y++ ] = *(pbPrBuffer + i++);
1694 }
1695 scratch[ y ] = 0;
1696
1697 /* See if there is a translation string */
1698
1699 if ( *( pbPrBuffer + i ) == '/' )
1700 {
1701 pcSlash = pbPrBuffer + (i++) + 1; /* don't need slash */
1702 while( *pcSlash != ':' ) /* There is so copy it over */
1703 {
1704 achOldSuffix[ j++ ] = *(pcSlash++);
1705 i++;
1706 }
1707 }
1708 achOldSuffix[ j ] = '\0'; /* If no slash OldSuffix will be null */
1709
1710 pTempBlock = pBlock;
1711 QueryEntryFromOption( (PBYTE) pbItemsBuffer, pTempBlock,
1712 (PBYTE) scratch, (PINT) &y );
1713 *((PSHORT) (pbItemsBuffer + cbBuffout)) = (SHORT) y;
1714 cbBuffout += 2;
1715 /*
1716 ** Bottom left X corner.
1717 ** Round up to nearest integer.
1718 */
1719 roundImgAreaVals( &i, ROUND_FLOAT, '"' );
1720
1721 /*
1722 ** Bottom left y corner.
1723 ** Round up to nearest integer.
1724 */
1725 roundImgAreaVals( &i, ROUND_FLOAT, ' ' );
1726
1727 /*
1728 ** Top right x corner.
1729 ** Truncate floating point value.
1730 */
1731 roundImgAreaVals( &i, TRUNCATE_FLOAT, ' ' );
1732
1733 /*
1734 ** Top right y corner.
1735 ** Truncate floating point value.
1736 */
1737 roundImgAreaVals( &i, TRUNCATE_FLOAT, ' ' );
1738
1739 /* Copy the old name out into resource */
1740 strcpy( pbItemsBuffer + cbBuffout, achOldSuffix );
1741 cbBuffout += strlen( achOldSuffix ) + 1;
1742
1743 k++;
1744 }
1745 desPpd.desPage.iImgpgpairs = k;
1746 }
1747 else
1748 {
1749 desPpd.desPage.iDmpgpairs = 0;
1750 desPpd.desPage.ofsDimxyPgsz = 0;
1751
1752 desPpd.desPage.iImgpgpairs = 0;
1753 desPpd.desPage.ofsImgblPgsz = 0;
1754 }
1755
1756 ProcessUIConstraints( );
1757 VerifyUICList( );
1758
1759 /*
1760 ** Read the fonts name list supported by printer
1761 */
1762
1763 fbseek( &fbIn, (long)0, SEEK_SET );
1764
1765 /*
1766 ** count of pairs formed
1767 */
1768
1769 k = 0;
1770 desPpd.desFonts.ofsFontnames = cbBuffout;
1771
1772 /*
1773 */
1774 while (ScanParam( szSearch[fontnamelist], pbPrBuffer))
1775 {
1776 for (j = 0 ; j < 32 ; j++)
1777 {
1778
1779 if (isspace( pbPrBuffer[ j ] ) || pbPrBuffer[ j ] == ':' ||
1780 pbPrBuffer[ j ] == 0)
1781 {
1782 pbPrBuffer[ j ] = 0;
1783 break;
1784 }
1785 }
1786
1787 if(j) // just checking...
1788 {
1789 strcpy(pbItemsBuffer + cbBuffout,pbPrBuffer);
1790 cbBuffout += strlen(pbPrBuffer) + 1; // terminator too
1791
1792 k++;
1793 }
1794 }
1795 desPpd.desFonts.iFonts = k;
1796 ProcessFormTable();
1797
1798 fbclose( &fbIn );
1799//desPpd.desItems.iSizeBuffer = cbBuffout;
1800 desPpd.desItems.iSizeBuffer = cbBuffout + iShrinkage;
1801 return( TRUE );
1802}
1803
1804
1805
1806/*
1807** V2.191412
1808** New function.
1809*/
1810/***************************************************************************
1811 *
1812 * FUNCTION NAME = VerifyPPDLineSize
1813 *
1814 * DESCRIPTION = Since a PPD line with a quoted value may exceed one
1815 * physical file line, it is important to verify that the
1816 * current PPD line that is being read does not exceed the
1817 * buffer. If the PPD line does exceed the buffer, the
1818 * compiler is not equipped to handle oversized lines, so the
1819 * specific command must be ignored.
1820 * This function verifies that the line does not exceed the
1821 * buffer by searching for both starting and ending quotes of
1822 * the quoted value. If the starting quote exists, the value
1823 * is a quoted value and the function searches for the ending
1824 * quote. If an ending quote is found, the line does not
1825 * exceed the buffer. If an ending quote is not found, the
1826 * line exceeds the buffer and the function returns an error.
1827 *
1828 * INPUT = pBuffer - Pointer to buffer containing current PPD line.
1829 * OUTPUT = NONE.
1830 *
1831 * RETURN-NORMAL = TRUE - Buffer does not exceed IBUFFSIZE bytes.
1832 * RETURN-ERROR = FALSE - Buffer exceeds IBUFFSIZE bytes.
1833 *
1834 ************************************************************************* */
1835BOOL VerifyPPDLineSize( PCHAR pBuffer )
1836{
1837 UINT uiLoop1;
1838 UINT uiLoop2;
1839 BOOL bRC = TRUE;
1840
1841 /*
1842 ** Search for the first quote.
1843 */
1844 for (uiLoop1 = 0 ; uiLoop1 < IBUFFSIZE ; uiLoop1++)
1845 {
1846 if (*(pBuffer + uiLoop1) == '"')
1847 {
1848 break;
1849 }
1850 }
1851
1852 /*
1853 ** In the above loop, if uiLoop1 is IBUFFSIZE, it could not find a starting
1854 ** quote. Otherwise, a starting quote was found so find the ending quote.
1855 */
1856 // there have been occurances of statistically very unprobable event when
1857 // quote occurs JUST BEFORE end of the buffer. then the closing brace is
1858 // out of range and invisible! which would cause all the buffer to be discarded...
1859 // so, if the string starts very close to end of buffer, ignore it.
1860 if (uiLoop1 < IBUFFSIZE - 100 )
1861 {
1862 for (uiLoop2 = uiLoop1 + 1 ; uiLoop2 < IBUFFSIZE ; uiLoop2++)
1863 {
1864 if (*(pBuffer + uiLoop2) == '"')
1865 {
1866 break;
1867 }
1868 }
1869
1870 /*
1871 ** If uiLoop2 equals IBUFFSIZE, no ending quote was found. The buffer
1872 ** was exceeded.
1873 */
1874 if (uiLoop2 == IBUFFSIZE)
1875 {
1876 /*
1877 ** Since this compiler passes the PPD file for each command, if a
1878 ** specific command exceeded the buffer, an error will be generated for
1879 ** each pass. Rather than display the same error for each pass, display
1880 ** the error for the first pass only.
1881 */
1882 if (BErrorWasDisplayed == FALSE)
1883 {
1884//print all buffer
1885// strtok( pBuffer, " " );
1886 /*
1887 ** Change "ERROR" to "INFO". This was confusing the build group.
1888 ** They were thinking that an error occurred and that the build was
1889 ** not successful.
1890 */
1891 printf( "[WARNING: Command %s, line exceeds maximum buffer size of %u bytes.\nThis line is ignored.]\n",
1892 pBuffer, IBUFFSIZE );
1893 }
1894 BErrorWasDisplayed = TRUE;
1895 bRC = FALSE;
1896 }
1897 }
1898
1899 return( bRC );
1900}
1901
1902
1903#define PUIB_IGNORE_MEDIA 0x00
1904#define PUIB_SEARCH_MEDIA 0x01
1905#define PUIB_MEDIA_FOUND 0x02
1906#define PUIB_CREATE_MEDIA 0x04
1907#define PUIB_MEDIA_CREATED 0x08
1908
1909/*
1910*/
1911VOID ProcessUIList( )
1912{
1913 PCHAR pUICurrBlock;
1914 PCHAR pEndToken;
1915 UINT uiStrLen;
1916 SHORT sDisplayOrder;
1917 UINT uiLoop, uiLoop2;
1918 long usFileLoc;
1919 PUI_BLOCK pUIBlock1, pUIBlock2;
1920 PUI_LIST pUIList = &desPpd.stUIList;
1921
1922 PCHAR pTemp;
1923 INT ofsTemp;
1924 PSZ pUICmd;
1925 USHORT usCMDLoop;
1926 USHORT usFlags = PUIB_SEARCH_MEDIA;
1927
1928 BUI = TRUE;
1929 memset( USBlockHeader, 0, sizeof( USBlockHeader ) );
1930
1931
1932 if (pUIList->pBlockList != NULL)
1933 {
1934 pUICmd = (PSZ) szSearch[ OpenUI ];
1935 for (usCMDLoop = 0 ; usCMDLoop <= 1 ; usCMDLoop++)
1936 {
1937 pUICurrBlock = (PCHAR) pUIList->pBlockList;
1938 fbseek( &fbIn, (long) 0, SEEK_SET );
1939
1940 while (ScanParam( pUICmd, pbPrBuffer ))
1941 {
1942 pEndToken = pbPrBuffer;
1943 while (*pEndToken != '/' && *pEndToken != ':')
1944 {
1945 pEndToken++;
1946 }
1947 uiStrLen = (UINT) (pEndToken - pbPrBuffer);
1948
1949 /*
1950 ** Query the UI string list to see if the name already exists.
1951 ** Process the UI if the string does not exist.
1952 */
1953 for (uiLoop = 0 ; uiLoop < maximum ; uiLoop++)
1954 {
1955 printf("%s\n",szSearch[uiLoop]);
1956 if (!strncmp( pbPrBuffer, szSearch[ uiLoop ], uiStrLen ))
1957 {
1958 break;
1959 }
1960 }
1961
1962 /*
1963 ** If uiLoop = maximum, then no matching strings were found in the
1964 ** above IF statement.
1965 */
1966 /*
1967 ** *IMPORTANT
1968 ** 'ColorAdjust' is used by Brother HS-1PS2. The problem with this
1969 ** command is that the command string is more than 2K in size.
1970 ** Incrementing the buffer more than 2K broke other parts of the
1971 ** compiler. Ignore this command, just for the time being.
1972 */
1973 if (uiLoop == maximum /*&& strncmp( pbPrBuffer, "*ColorAdjust", 12 )*/)
1974 {
1975 USBlockHeader[ pUIList->usNumOfBlocks++ ] =
1976 pUIList->usBlockListSize;
1977 pUIBlock1 = (PUI_BLOCK) (pUICurrBlock + pUIList->usBlockListSize);
1978
1979 usFileLoc = fbtell( &fbIn );
1980 if (usFileLoc > UIFileGroup.usFileStart &&
1981 usFileLoc < UIFileGroup.usFileEnd)
1982 {
1983 pUIBlock1->ucGroupType = UIGT_INSTALLABLEOPTION;
1984 }
1985 else
1986 {
1987 pUIBlock1->ucGroupType = UIGT_DEFAULTOPTION;
1988 }
1989
1990 pUIList->usBlockListSize += (USHORT) ProcessUIBlock( pUIList,
1991 pUIBlock1,
1992 uiStrLen,
1993 &usFlags );
1994
1995
1996 /* ** If last UI Block was InputSlot and there are MediaType
1997 ** simulate new UI Block MediaType
1998 */
1999 if ( usFlags & PUIB_MEDIA_FOUND )
2000 {
2001 if ( nErrorLogLevel<2 )
2002 printf("[INFO: MediaType Simulation]\n");
2003 usFlags = PUIB_CREATE_MEDIA;
2004
2005 USBlockHeader[ pUIList->usNumOfBlocks++ ] =
2006 pUIList->usBlockListSize;
2007
2008 pUIBlock1 = (PUI_BLOCK) (pUICurrBlock + pUIList->usBlockListSize);
2009 pUIBlock1->ucGroupType = UIGT_DEFAULTOPTION;
2010
2011 pUIList->usBlockListSize += (USHORT) ProcessUIBlock( pUIList,
2012 pUIBlock1,
2013 uiStrLen,
2014 &usFlags );
2015 usFlags = PUIB_MEDIA_CREATED;
2016 }
2017
2018 }
2019 }
2020
2021 pUICmd = (PSZ) szSearch[ JCLOpenUI ];
2022 }
2023
2024 /*
2025 ** Now that the UI's have been processed, it is time to sort them.
2026 ** They will be sorted in order, from low to high value, taken from
2027 ** the "*OrderDependency" command in the UI block. Each command
2028 ** is followed by a numeric value.
2029 */
2030
2031 if (pUIList->usNumOfBlocks > 0)
2032 {
2033 sDisplayOrder = 0;
2034 for (uiLoop = 0 ; uiLoop < pUIList->usNumOfBlocks ; uiLoop++)
2035 {
2036 pUIBlock1 = (PUI_BLOCK) ((PCHAR) pUIList->pBlockList +
2037 USBlockHeader[ uiLoop ]);
2038 pUIBlock1->usDisplayOrder = (USHORT) sDisplayOrder++;
2039
2040 /*
2041 ** If "JCLResolution" is found, then treat it as a standard
2042 ** resolution. Do this by converting the offset to point to
2043 ** "Resolution", rather than "JCLResoluton".
2044 */
2045 pTemp = (PCHAR) (pbItemsBuffer + pUIBlock1->ofsUIName);
2046 if (!strcmp( pTemp, "JCLResolution" ))
2047 {
2048 // Increment by 3 to skip past "JCL".
2049 pUIBlock1->ofsUIName += 3;
2050 }
2051
2052
2053 if (pUIBlock1->usUILocation == 0)
2054 {
2055 pUIBlock1->usUILocation = UI_ORDER_PROLOGSETUP;
2056 }
2057 }
2058
2059 DosAllocMem( (PPVOID) &pTemp, 12288,//8192,
2060 PAG_READ | PAG_WRITE | PAG_COMMIT );
2061 ofsTemp = 0;
2062
2063 for (uiLoop = 0 ; uiLoop < pUIList->usNumOfBlocks ; uiLoop++)
2064 {
2065 for (uiLoop2 = 0 ; uiLoop2 < pUIList->usNumOfBlocks - 1 ; uiLoop2++)
2066 {
2067 pUIBlock1 = (PUI_BLOCK) ((PCHAR) pUIList->pBlockList +
2068 USBlockHeader[ uiLoop2 ]);
2069 pEndToken = (PCHAR) (pUIBlock1->ofsUIName + pbItemsBuffer);
2070
2071 pUIBlock2 = (PUI_BLOCK) ((PCHAR) pUIList->pBlockList +
2072 USBlockHeader[ uiLoop2 + 1 ]);
2073 pEndToken = (PCHAR) (pUIBlock2->ofsUIName + pbItemsBuffer);
2074
2075 if (pUIBlock1->usOrderDep > pUIBlock2->usOrderDep)
2076 {
2077 ofsTemp = USBlockHeader[ uiLoop2 ];
2078 USBlockHeader[ uiLoop2 ] = USBlockHeader[ uiLoop2 + 1 ];
2079 USBlockHeader[ uiLoop2 + 1 ] = ofsTemp;
2080 }
2081 }
2082 }
2083
2084 ofsTemp = 0;
2085 for (uiLoop = 0 ; uiLoop < pUIList->usNumOfBlocks ; uiLoop++)
2086 {
2087 pUIBlock1 = (PUI_BLOCK) ((PCHAR) pUIList->pBlockList +
2088 USBlockHeader[ uiLoop ]);
2089 pUIBlock1->usOrderDep = (USHORT) uiLoop;
2090 pEndToken = (PCHAR) (pUIBlock1->ofsUIName + pbItemsBuffer);
2091 memcpy( pTemp + ofsTemp, pUIBlock1, QUERY_BLOCK_SIZE( pUIBlock1 ) );
2092 ofsTemp += QUERY_BLOCK_SIZE( pUIBlock1 );
2093 }
2094
2095 memcpy( pUIList->pBlockList, pTemp, pUIList->usBlockListSize );
2096
2097 DosFreeMem( pTemp );
2098 }
2099
2100 pbPrBuffer[ 0 ] = 0;
2101 }
2102
2103// DosFreeMem( pUIList->pBlockList );
2104 BUI = FALSE;
2105}
2106
2107
2108
2109UINT ProcessUIBlock( PUI_LIST pUIList, PUI_BLOCK pUIBlock, UINT uiStrLen, PUSHORT pusFlags )
2110{
2111 CHAR aTempDefName[ 31 ];
2112 INT iLoop;
2113 INT iCounter;
2114 UINT uiEndOfString;
2115 PCHAR pTransString;
2116#ifdef DEBUG
2117 PCHAR pStorage = pbItemsBuffer + cbBuffout;
2118 PCHAR pLine = pbPrBuffer + uiStrLen;
2119#endif
2120 PCHAR pCompare;
2121 CHAR cGroupType;
2122 PCHAR pKeyword;
2123
2124//PSZ pTemp; NOTUSED
2125 BOOL bInputSlot = FALSE;
2126 BOOL bSkipEntry;
2127
2128 cGroupType = pUIBlock->ucGroupType;
2129 memset( pUIBlock, 0, sizeof( UI_BLOCK ) - sizeof( UI_ENTRY ) );
2130 pUIBlock->ucGroupType = cGroupType;
2131
2132 /* ** If PUIB_CREATE_MEDIA then simulating Media type
2133 */
2134 if ( *pusFlags & PUIB_CREATE_MEDIA )
2135 {
2136 bInputSlot = TRUE;
2137 if ((pUIBlock->ofsUIName = (USHORT) MatchKeywords( UINAME_MEDIATYPE, pUIList,
2138 pbItemsBuffer, TRUE )) == (USHORT) -1)
2139 {
2140 pUIBlock->ofsUIName = cbBuffout;
2141 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
2142 UINAME_MEDIATYPE,
2143 255,
2144 CSTR_INCLUDE_SLASH );
2145 }
2146
2147 pUIBlock->ucPanelID = UIP_PREDEF_FEATURE;
2148 }
2149 else
2150 {
2151
2152 // Search for keyword to replace current UI block keyword
2153 pKeyword = SearchKeySubst( pbPrBuffer + 1 );
2154
2155 if ((pUIBlock->ofsUIName = (USHORT) MatchKeywords( pKeyword, pUIList,
2156 pbItemsBuffer, TRUE )) == (USHORT) -1)
2157 {
2158 pUIBlock->ofsUIName = cbBuffout;
2159 pCompare = pbItemsBuffer + cbBuffout;
2160 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
2161 pKeyword,
2162 255,
2163 CSTR_INCLUDE_SLASH );
2164 }
2165 /*
2166 ** If a name already exists, we still need to extract it to verify if it
2167 ** is a predefined UI or not.
2168 */
2169 else
2170 {
2171 pCompare = aTempDefName;
2172 pTransString = pbPrBuffer + 1;
2173 iLoop = 0;
2174
2175 while (*pTransString != ' ' && *pTransString != ':')
2176 {
2177 aTempDefName[ iLoop ] = *pTransString;
2178 pTransString++;
2179 iLoop++;
2180 }
2181 aTempDefName[ iLoop ] = 0;
2182 pCompare = SearchKeySubst( aTempDefName );
2183
2184 }
2185
2186 /* ** Search for UI Block=InputSlot if PUIB_SEARCH_MEDIA
2187 */
2188 if( ( *pusFlags & PUIB_SEARCH_MEDIA ) &&
2189 !strcmpi( UINAME_INPUTSLOT, pCompare ))
2190 {
2191 bInputSlot = TRUE;
2192 }
2193
2194
2195 // see if this is a predefined feature
2196 pUIBlock->ucPanelID = UIP_OS2_FEATURE;
2197 for( iLoop = 0; iLoop < MAX_PREDEFINED ; iLoop++ )
2198 {
2199
2200 // if( !strcmp( szPredefined[iLoop], pCompare ))
2201 if( !strcmpi( szPredefined[iLoop], pCompare ))
2202 pUIBlock->ucPanelID = UIP_PREDEF_FEATURE;
2203 }
2204
2205 }
2206
2207 /*
2208 ** Copy the translation string.
2209 */
2210 if (*(pbPrBuffer + uiStrLen) == '/' && pUIBlock->ucPanelID !=
2211 UIP_PREDEF_FEATURE)
2212 {
2213 if ((pUIBlock->ofsUITransString =
2214 (USHORT) MatchKeywords( pbPrBuffer + ++uiStrLen, pUIList,
2215 pbItemsBuffer, TRUE )) == (USHORT) -1)
2216 {
2217 pUIBlock->ofsUITransString = cbBuffout;
2218 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
2219 pbPrBuffer + uiStrLen,
2220 255,
2221 CSTR_INCLUDE_SLASH | CSTR_HEX2CHAR);
2222 }
2223 }
2224 else
2225 {
2226 /*
2227 ** Assign the UI name as the Translation string since a Translation
2228 ** string wasn't provided. Ignore the asterisk ('*') for the
2229 ** Translation string.
2230 */
2231
2232 // adding 1 caused the first character of the UI name
2233 // to be chopped of in cases where the PPD had a variable
2234 // number of spaces before the '*'. MovePast has been
2235 // changed to handle this.
2236// pUIBlock->ofsUITransString = pUIBlock->ofsUIName + 1;
2237 pUIBlock->ofsUITransString = pUIBlock->ofsUIName;
2238 }
2239
2240 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ':' );
2241 uiStrLen += SkipBlank( pbPrBuffer + uiStrLen );
2242 uiEndOfString = MovePast( pbPrBuffer + uiStrLen, '\n' );
2243
2244#ifdef DEBUG
2245 pStorage = pbItemsBuffer + cbBuffout;
2246 pLine = pbPrBuffer + uiStrLen;
2247#endif
2248
2249 /*
2250 ** The UI has three types of selections: BOOLEAN, PICK ONE, and
2251 ** PICK MANY.
2252 */
2253 if (!strncmp( pbPrBuffer + uiStrLen, "Boolean", 7 ))
2254 {
2255 pUIBlock->usSelectType = (UCHAR) UI_SELECT_BOOLEAN;
2256 }
2257 else if (!strncmp( pbPrBuffer + uiStrLen, "PickMany", 8 ))
2258 {
2259 printf( "[WARNING: UI type PickMany will cause problems]\n" );
2260
2261 pUIBlock->usSelectType = (UCHAR) UI_SELECT_PICKMANY;
2262 }
2263 else
2264 {
2265 pUIBlock->usSelectType = (UCHAR) UI_SELECT_PICKONE;
2266 }
2267
2268 /*
2269 ** Go to the next line.
2270 */
2271
2272 uiStrLen += uiEndOfString;
2273
2274 /*
2275 ** Run through the loop until a CLOSEUI is encountered.
2276 */
2277 while (TRUE)
2278 {
2279#ifdef DEBUG
2280 pStorage = pbItemsBuffer + cbBuffout;
2281 pLine = pbPrBuffer + uiStrLen;
2282#endif
2283
2284 if (*(pbPrBuffer + uiStrLen) == 0 &&
2285 *(pbPrBuffer + uiStrLen + 1) == 0)
2286 {
2287 fbread( pbPrBuffer, 1, IBUFFSIZE, &fbIn );
2288 uiStrLen = 0;
2289 }
2290
2291 /*
2292 ** Parse the appropriate key.
2293 */
2294 if (!strncmp( pbPrBuffer + uiStrLen, "*Default", 8 ))
2295 {
2296 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ':' );
2297 uiStrLen += SkipBlank( pbPrBuffer + uiStrLen );
2298
2299 CopyString( aTempDefName,
2300 pbPrBuffer + uiStrLen,
2301 31,
2302 CSTR_NORMAL );
2303 /* ** Tektronic printers have Transparent medias in InputSlot block.
2304 ** Parser should ignore them. Search for DefaultInputSlot: Papar or AutoSelect
2305 ** FYI - Kyocera printers DefaultInputSlot: Internal or PF30A
2306 */
2307 if( ( bInputSlot ) &&
2308 ( *pusFlags & PUIB_SEARCH_MEDIA ) &&
2309 ( ( !strcmp( aTempDefName, "Paper") ) ||
2310 ( !strcmp( aTempDefName, "AutoSelect") ) ) )
2311 {
2312 *pusFlags = PUIB_IGNORE_MEDIA;
2313 bInputSlot = FALSE;
2314 }
2315
2316 }
2317 else if (!strncmp( pbPrBuffer + uiStrLen, "*OrderDependency", 16 ) ||
2318 !strncmp( pbPrBuffer + uiStrLen, "OrderDependency", 15 ))
2319 {
2320 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ':' );
2321 uiStrLen += SkipBlank( pbPrBuffer + uiStrLen );
2322
2323 pUIBlock->usOrderDep = atoi( pbPrBuffer + uiStrLen );
2324
2325 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ' ' );
2326 uiStrLen += SkipBlank( pbPrBuffer + uiStrLen );
2327 uiEndOfString = MovePast( pbPrBuffer + uiStrLen, ' ' );
2328
2329 if (!strncmp( pbPrBuffer + uiStrLen, "ExitServer", 10 ))
2330 {
2331 pUIBlock->usUILocation = UI_ORDER_EXITSERVER;
2332 }
2333 else if (!strncmp( pbPrBuffer + uiStrLen, "DocumentSetup", 13 ))
2334 {
2335 pUIBlock->usUILocation = UI_ORDER_DOCSETUP;
2336 }
2337 else if (!strncmp( pbPrBuffer + uiStrLen, "PageSetup", 9 ))
2338 {
2339 pUIBlock->usUILocation = UI_ORDER_PAGESETUP;
2340 }
2341 else if (!strncmp( pbPrBuffer + uiStrLen, "JCLSetup", 8 ))
2342 {
2343 pUIBlock->usUILocation = UI_ORDER_JCLSETUP;
2344 }
2345 else
2346 {
2347 pUIBlock->usUILocation = UI_ORDER_PROLOGSETUP;
2348 }
2349 }
2350 else if (!strncmp( pbPrBuffer + uiStrLen, "*CloseUI", 8 ) ||
2351 !strncmp( pbPrBuffer + uiStrLen, "*JCLCloseUI", 11 ) ||
2352 pUIBlock->usNumOfEntries >= 100 ) // bvl: Increased to 100 from 30 ( can't we just skip this in total if the buffer is large enough ?? )
2353 {
2354 break;
2355 }
2356 else if (*(pbPrBuffer + uiStrLen) == '*' &&
2357 *(pbPrBuffer + uiStrLen + 1) != '?' &&
2358 *(pbPrBuffer + uiStrLen + 1) != '%' &&
2359 strncmp( pbPrBuffer + uiStrLen, "*End", 4 ))
2360 {
2361 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ' ' );
2362 bSkipEntry = FALSE;
2363
2364 // bvl: if we are in resolution, we need to check the whole string for "" this is invalid
2365
2366 if(stricmp(pCompare,"Resolution")==0)
2367 {
2368 ULONG uiResStr;
2369 // we are in resolution processing
2370 uiResStr = uiStrLen + MovePast( pbPrBuffer + uiStrLen, ':' );
2371 uiResStr += SkipBlank( pbPrBuffer + uiResStr );
2372 if(strnicmp(pbPrBuffer+uiResStr,"\"\"",2)==0)
2373 {
2374 // we found a empty resolution string so skip this one
2375 bSkipEntry = TRUE;
2376 }
2377 }
2378
2379 /* */
2380
2381 if ( bInputSlot )
2382 {
2383 if ( *pusFlags & PUIB_CREATE_MEDIA )
2384 bSkipEntry = TRUE;
2385 for(iCounter = 0; iCounter < 100; iCounter++ )
2386 {
2387 if ((*(pbPrBuffer + uiStrLen + iCounter) == '>') &&
2388 (*(pbPrBuffer + uiStrLen + (iCounter+1)) == '>'))break;
2389 if(!strncmp( pbPrBuffer + uiStrLen + iCounter ,
2390 "MediaType ()" , strlen("MediaType (")))
2391 {
2392 *pusFlags |= PUIB_MEDIA_FOUND;
2393 bSkipEntry = !bSkipEntry;
2394 break;
2395 }
2396 if(!strncmp( pbPrBuffer + uiStrLen + iCounter , "*End" , strlen("*End"))) break;
2397 }
2398 }
2399
2400 if ( bSkipEntry )
2401 {
2402 goto SkipEntry;
2403 }
2404
2405 if ((pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsOption =
2406 (USHORT) MatchKeywords( pbPrBuffer + uiStrLen, pUIList,
2407 pbItemsBuffer, TRUE )) == (USHORT) -1)
2408 {
2409 pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsOption = cbBuffout;
2410 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
2411 pbPrBuffer + uiStrLen,
2412 31,
2413 CSTR_INCLUDE_SLASH );
2414 }
2415
2416 pTransString = pbPrBuffer + uiStrLen;
2417 while (*pTransString != '/' && *pTransString != ':')
2418 {
2419 pTransString++;
2420 }
2421
2422 if (*pTransString == '/')
2423 {
2424 if ((pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsTransString =
2425 (USHORT) MatchKeywords( ++pTransString, pUIList, pbItemsBuffer,
2426 TRUE )) == (USHORT) -1)
2427 {
2428 pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsTransString =
2429 cbBuffout;
2430 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
2431 pTransString,
2432
2433 64,
2434 CSTR_NORMAL | CSTR_HEX2CHAR | CSTR_EXCLUDE_DQUOTE );
2435 }
2436 }
2437 else
2438 {
2439 pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsTransString =
2440 pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsOption;
2441 }
2442 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ':' );
2443 uiStrLen += SkipBlank( pbPrBuffer + uiStrLen );
2444//// No needed that hex strings are done
2445//// if (pUIBlock->usUILocation == UI_ORDER_JCLSETUP)
2446//// {
2447//// pTemp = (PSZ) (pbPrBuffer + uiStrLen + 2);
2448////
2449//// while (*pTemp != '"')
2450//// {
2451//// pTemp++;
2452//// }
2453////
2454//// if (*(pTemp - 1) == '>')
2455//// {
2456//// *pTemp = ' ';
2457//// while (*pTemp != '<')
2458//// {
2459//// pTemp--;
2460//// }
2461//// *pTemp = '"';
2462//// }
2463//// }
2464
2465 pUIBlock->uiEntry[ pUIBlock->usNumOfEntries ].ofsValue = cbBuffout;
2466 iLoop = CopyInQuote( pbItemsBuffer + cbBuffout, pbPrBuffer +
2467 ++uiStrLen, FALSE, COMPRESS );
2468 cbBuffout += iLoop;
2469
2470 if (pUIBlock->usUILocation == UI_ORDER_JCLSETUP)
2471 {
2472 *(pbItemsBuffer + cbBuffout - 1) = '\n';
2473 *(pbItemsBuffer + cbBuffout++) = 0;
2474 }
2475
2476 if (*(pbPrBuffer + uiStrLen - 1) == '"')
2477 {
2478 while (*(pbPrBuffer + uiStrLen) != '"')
2479 {
2480 uiStrLen++;
2481 }
2482 uiStrLen++;
2483 }
2484 else
2485 {
2486 uiStrLen += iLoop;
2487 }
2488
2489 pUIBlock->usNumOfEntries++;
2490 }
2491
2492SkipEntry:
2493 if (*(pbPrBuffer + uiStrLen) != '\n')
2494 {
2495 uiStrLen += MovePast( pbPrBuffer + uiStrLen, '\n' );
2496 }
2497 else
2498 {
2499 uiStrLen++;
2500 }
2501 }
2502
2503 /*
2504 ** Run through the list of entries in the current block and find
2505 ** the default entry name. The reason the list starts at the
2506 ** bottom is so if no matching names are found, the default is assigned
2507 ** to the first entry, which is the last one to be encountered in
2508 ** this loop.
2509 */
2510 for (iLoop = pUIBlock->usNumOfEntries - 1 ; iLoop >= 0 ; iLoop--)
2511 {
2512 /*
2513 ** If a match is found, get out of the loop.
2514 */
2515 if (iLoop == 0 ||
2516 !strcmp( pbItemsBuffer + pUIBlock->uiEntry[ iLoop ].ofsOption,
2517 aTempDefName ) )
2518 {
2519// pUIBlock->usDefaultEntry = (USHORT) (1 << iLoop);
2520 pUIBlock->usDefaultEntry = (USHORT) iLoop;
2521 break;
2522 }
2523 }
2524
2525 if (pUIBlock->usNumOfEntries > 0)
2526 {
2527 iLoop = (INT) pUIBlock->usNumOfEntries - 1;
2528 }
2529 else
2530 {
2531 iLoop = 0;
2532 }
2533
2534 return( sizeof( UI_BLOCK ) + (sizeof( UI_ENTRY ) * iLoop) );
2535}
2536
2537/*
2538** Function SearchKeySubst
2539** This function search pKeyToSearch in SRKeywords massive
2540** If founds returns Keyword need to replace with
2541** If not returns pKeyToSearch
2542*/
2543PCHAR SearchKeySubst( PCHAR pKeyToSearch )
2544{
2545 INT iLoop;
2546 CHAR aKey[ MAX_PSIZE ]; // Key string to compare
2547
2548 CopyString( aKey, pKeyToSearch, MAX_PSIZE, CSTR_INCLUDE_SLASH );
2549
2550 for ( iLoop = 0; SRKeywords[ iLoop ].szSearch ; iLoop++ )
2551 {
2552 if ( !strcmp( aKey, SRKeywords[ iLoop ].szSearch ) )
2553 {
2554 return SRKeywords[ iLoop ].szReplace;
2555 }
2556 }
2557
2558 return pKeyToSearch;
2559}
2560
2561
2562
2563
2564INT MatchKeywords( PBYTE pKeyToMatch, PUI_LIST pUIList, PBYTE pPPBBuff,
2565 BOOL bCompareEntries )
2566{
2567 CHAR aKey[ MAX_PSIZE ]; // Key string to compare
2568 INT iListIndex; // List Index counter
2569 INT iBlockIndex; // Block index counter
2570 PBYTE pKeyword; // Current UI keyword/T.S.
2571 PUI_ENTRY pUIEntry; // UI entry pointer
2572 PUI_BLOCK pUIBlock = pUIList->pBlockList; // UI Block pointer
2573 INT iRC = -1; // Return code
2574
2575 /*
2576 ** At this point, pKeyToMatch points to the current keyword, but it is not
2577 ** NULL-terminated. Copy the keyword to a temporary buffer so that it is
2578 ** NULL-terminated. It is not recommended to insert a 0 in pKeyToMatch since
2579 ** that pointer points to the actual PPD string data.
2580 */
2581 CopyString( aKey, pKeyToMatch, MAX_PSIZE, CSTR_INCLUDE_SLASH );
2582
2583 /*
2584 ** Run through the UI list.
2585 */
2586 for (iListIndex = 0 ; iListIndex < (INT) pUIList->usNumOfBlocks - 1 ;
2587 iListIndex++)
2588 {
2589 pKeyword = (PBYTE) (pUIBlock->ofsUIName + pPPBBuff);
2590
2591 /*
2592 ** Compare the current keyword with the string to match.
2593 ** Set the return code to the offset if a match is found.
2594 */
2595 if (!strcmp( pKeyword, aKey ))
2596 {
2597 iRC = (INT) pUIBlock->ofsUIName;
2598 break;
2599 }
2600
2601 /*
2602 ** Compare the Translation String only if the T.S. is not the same as
2603 ** as the keyword for this has already been done above.
2604 */
2605 if (pUIBlock->ofsUIName != pUIBlock->ofsUITransString)
2606 {
2607 pKeyword = (PBYTE) (pUIBlock->ofsUITransString + pPPBBuff);
2608 if (!strcmp( pKeyword, aKey ))
2609 {
2610 /*
2611 ** Copy T.S. offset, not UI name offset.
2612 */
2613// iRC = (INT) pUIBlock->ofsUIName;
2614 iRC = (INT) pUIBlock->ofsUITransString;
2615 break;
2616 }
2617 }
2618
2619 /*
2620 ** Compare entries, only if requested.
2621 */
2622 if (bCompareEntries == TRUE)
2623 {
2624 /*
2625 ** At this point, no match has been found. At this time, compare the
2626 ** keywords and the Translation Strings for each entry in the current
2627 ** block.
2628 */
2629 for (iBlockIndex = 0 ; iBlockIndex < (INT) pUIBlock->usNumOfEntries ;
2630 iBlockIndex++)
2631 {
2632 pUIEntry = &pUIBlock->uiEntry[ iBlockIndex ];
2633
2634 /*
2635 ** Compare the entry's keyword.
2636 */
2637 pKeyword = (PBYTE) (pUIEntry->ofsOption + pPPBBuff);
2638 if (!strcmp( pKeyword, aKey ))
2639 {
2640 iRC = (INT) pUIEntry->ofsOption;
2641 break;
2642 }
2643
2644 /*
2645 ** Compare the entry's Translation String, provided that the offset to
2646 ** the T.S. is not the same as the keyword.
2647 */
2648 if (pUIEntry->ofsTransString != pUIEntry->ofsOption)
2649 {
2650 pKeyword = (PBYTE) (pUIEntry->ofsTransString + pPPBBuff);
2651 if (!strcmp( pKeyword, aKey ))
2652 {
2653 iRC = (INT) pUIEntry->ofsTransString;
2654 break;
2655 }
2656 }
2657 }
2658 }
2659
2660 INCREMENT_BLOCK_PTR( pUIBlock );
2661 }
2662
2663 return( iRC );
2664}
2665
2666
2667
2668//
2669// WORK MORE MAGIC pt.1
2670//
2671
2672INT ProcessUIConstraints( )
2673{
2674 LONG ofsBlock1 = 0;
2675 LONG ofsBlock2 = 0;
2676 CHAR aKeyword1[ MAX_PSIZE ];
2677 CHAR aOption1[ MAX_PSIZE ];
2678 CHAR aKeyword2[ MAX_PSIZE ];
2679 CHAR aOption2[ MAX_PSIZE ];
2680 ULONG uOptionBit1, uOptionBit2;
2681 PUI_BLOCK pBlock1;
2682 PUI_BLOCK pBlock2;
2683//PUIC_ENTRY pUICEntry1; NOTUSED
2684//PUIC_ENTRY pUICEntry2; NOTUESD
2685 INT ofsOption = 0;
2686 PUIC_LIST pUICList;
2687 PUIC_BLOCK pUICCompare;
2688 UINT uiStrLen;
2689 INT iUICIndex;
2690 PUI_LIST pUIList = &desPpd.stUIList;
2691 PUIC_BLOCK pUICBlock = desPpd.stUICList.puicBlockList;
2692 INT iRC = cbBuffout;
2693
2694//PUIC_BLOCK pUICTemp; NOTUSED
2695
2696 pUICList = &desPpd.stUICList;
2697 pUICList->puicBlockList = pUICList->puicBlockList;
2698
2699 fbseek( &fbIn, (LONG) 0, SEEK_SET );
2700
2701 while (ScanParam( szSearch[ UIConstraints ], pbPrBuffer ))
2702 {
2703 /*
2704 ** Set all arrays to NULL.
2705 */
2706 aKeyword1[ 0 ] = aKeyword2[ 0 ] = aOption1[ 0 ] = aOption2[ 0 ] = 0;
2707
2708 /*
2709 ** Retrieve the first keyword string. The first keyword is required.
2710 */
2711 uiStrLen = MovePast( pbPrBuffer, ' ' );
2712 CopyWord( aKeyword1, pbPrBuffer + uiStrLen + 1 );
2713
2714 /*
2715 ** Retrieve the first option string. The option string is optioal. An
2716 ** option string can be determined if the string does not begin with a '*'.
2717 */
2718 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ' ' );
2719 if (*(pbPrBuffer + uiStrLen) != '*')
2720 {
2721 CopyWord( aOption1, pbPrBuffer + uiStrLen );
2722 }
2723
2724 /*
2725 ** Retrieve the second keyword string. This string is also required.
2726 */
2727 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ' ' );
2728 if (*(pbPrBuffer + uiStrLen) != 0x0D && *(pbPrBuffer + uiStrLen) == '*')
2729 {
2730 CopyWord( aKeyword2, pbPrBuffer + uiStrLen + 1 );
2731 }
2732
2733 /*
2734 ** Retrieve the second option string. The option string is optioal. An
2735 ** option string can be determined if the string does not begin with a '*'.
2736 */
2737 uiStrLen += MovePast( pbPrBuffer + uiStrLen, ' ' );
2738 if (*(pbPrBuffer + uiStrLen) != 0x0D)
2739 {
2740 CopyWord( aOption2, pbPrBuffer + uiStrLen );
2741 }
2742
2743 /*
2744 ** From the keywords extracted above, query the respective UI blocks.
2745 */
2746 pBlock1 = QueryBlockFromKeyword( pUIList, pbItemsBuffer,
2747 SearchKeySubst ( aKeyword1 ),
2748 (PINT) &ofsBlock1 );
2749 pBlock2 = QueryBlockFromKeyword( pUIList, pbItemsBuffer,
2750 SearchKeySubst ( aKeyword2 ),
2751 (PINT) &ofsBlock2 );
2752
2753 /*
2754 ** If at least one block is NULL, then the keyword string is invalid. No
2755 ** processing needs to be done for invalid strings.
2756 */
2757 /*
2758 ** Do not include PageRegion in with the constraints. Constraints are
2759 ** reserved for UI blocks that have matching controls in either Printer
2760 ** or Job Properties, while PageRegion has no matching control (the form
2761 ** listbox is managed by PageSize).
2762 */
2763 if (pBlock1 != NULL && pBlock2 != NULL &&
2764 strcmp( aKeyword1, "PageRegion" ) && strcmp( aKeyword2, "PageRegion" ) )
2765 {
2766 /*
2767 ** If a valid option string is provided for the first and second
2768 ** keywords, then query the zero-based offset (ofsOption) of that entry.
2769 ** From that offset, set the appropriate zero-based bit (uOptionBit). If
2770 ** no option string exists for the appropriate keyword, then set all of
2771 ** the bits in uOptionBit to 1. This is because the lack of an option
2772 ** string for a keyword means that *ALL* options apply. Therefore, set
2773 ** all bits to 1.
2774 ** Again, this applies to both the first and second option (aOption1 and
2775 ** aOption2).
2776 */
2777 if (aOption1[ 0 ] != 0)
2778 {
2779 /*
2780 ** If the option string is invalid (no matching entry), then set
2781 ** the option bit to 0.
2782 */
2783 if (QueryEntryFromOption( pbItemsBuffer, pBlock1, aOption1,
2784 (PINT) &ofsOption ) != NULL)
2785 {
2786 uOptionBit1 = 1 << ofsOption;
2787 }
2788 else
2789 {
2790 uOptionBit1 = 0;
2791 }
2792 }
2793 else
2794 {
2795 /*
2796 ** The default value should never be a constraint.
2797 */
2798// uOptionBit1 = (ULONG) -1;
2799 uOptionBit1 = (ULONG) ~(1 << pBlock1->usDefaultEntry);
2800 }
2801
2802 if (aOption2[ 0 ] != 0)
2803 {
2804 /*
2805 ** If the option string is invalid (no matching entry), then set
2806 ** the option bit to 0.
2807 */
2808 if (QueryEntryFromOption( pbItemsBuffer, pBlock2, aOption2,
2809 (PINT) &ofsOption ) != NULL)
2810 {
2811 uOptionBit2 = 1 << ofsOption;
2812 }
2813 else
2814 {
2815 uOptionBit2 = 0;
2816 }
2817 }
2818 else
2819 {
2820 /*
2821 ** The default value should never be a constraint.
2822 */
2823// uOptionBit2 = (ULONG) -1;
2824 uOptionBit2 = (ULONG) ~(1 << pBlock2->usDefaultEntry);
2825 }
2826
2827 /*
2828 ** Just like the IF statement above for blocks, verify that the option
2829 ** selections are valid (not 0). If any option is invalid, then the
2830 ** constraint does not apply.
2831 */
2832 if (uOptionBit1 != 0 && uOptionBit2 != 0)
2833 {
2834 pUICCompare = pUICList->puicBlockList;
2835 for (iUICIndex = 0 ; iUICIndex < (INT) pUICList->usNumOfUICs ;
2836 iUICIndex++)
2837 {
2838 if (pUICCompare->uicEntry1.ofsUIBlock == ofsBlock1 &&
2839 pUICCompare->uicEntry2.ofsUIBlock == ofsBlock2)
2840 {
2841 if (pUICCompare->uicEntry1.bOption == uOptionBit1)
2842 {
2843 pUICCompare->uicEntry2.bOption |= uOptionBit2;
2844 break;
2845 }
2846 else if (pUICCompare->uicEntry2.bOption == uOptionBit2)
2847 {
2848 pUICCompare->uicEntry1.bOption |= uOptionBit1;
2849 break;
2850 }
2851 }
2852 else if (pUICCompare->uicEntry1.ofsUIBlock == ofsBlock2 &&
2853 pUICCompare->uicEntry2.ofsUIBlock == ofsBlock1)
2854 {
2855 if (pUICCompare->uicEntry1.bOption == uOptionBit2)
2856 {
2857 pUICCompare->uicEntry2.bOption |= uOptionBit1;
2858 break;
2859 }
2860 else if (pUICCompare->uicEntry2.bOption == uOptionBit1)
2861 {
2862 pUICCompare->uicEntry1.bOption |= uOptionBit2;
2863 break;
2864 }
2865 }
2866 pUICCompare++;
2867 }
2868
2869 if (iUICIndex >= (INT) pUICList->usNumOfUICs ||
2870 pUICList->usNumOfUICs == 0)
2871 {
2872 pUICBlock = pUICList->puicBlockList + pUICList->usNumOfUICs++;
2873
2874 pUICBlock->uicEntry1.ofsUIBlock = (USHORT) ofsBlock1;
2875 pUICBlock->uicEntry1.bOption = uOptionBit1;
2876
2877 pUICBlock->uicEntry2.ofsUIBlock = (USHORT) ofsBlock2;
2878 pUICBlock->uicEntry2.bOption = uOptionBit2;
2879 }
2880 }
2881 }
2882 }
2883
2884 return( iRC );
2885}
2886
2887
2888
2889
2890
2891PUI_BLOCK QueryBlockFromKeyword( PUI_LIST pUIList, PBYTE pPSStringBuff,
2892 PBYTE pKeyword, PINT pofsBlock )
2893{
2894 UINT uiLoop; // Local loop counter
2895 PBYTE pBlockName; // Name of current block
2896 PUI_BLOCK pInBlock = pUIList->pBlockList; // Input block pointer
2897 PUI_BLOCK pUIBlockRC = NULL; // Block return code
2898
2899 if (pofsBlock != NULL)
2900 {
2901 *pofsBlock = -1;
2902 }
2903
2904 for (uiLoop = 0 ; uiLoop < pUIList->usNumOfBlocks ; uiLoop++)
2905 {
2906 pBlockName = pInBlock->ofsUIName + pPSStringBuff;
2907
2908 if (!stricmp( pBlockName, pKeyword ))
2909 {
2910 pUIBlockRC = pInBlock;
2911
2912 if (pofsBlock != NULL)
2913 {
2914 *pofsBlock = (INT) uiLoop;
2915 }
2916
2917 break;
2918 }
2919
2920 INCREMENT_BLOCK_PTR( pInBlock );
2921 }
2922
2923 return( pUIBlockRC );
2924}
2925
2926
2927
2928
2929
2930PUI_ENTRY QueryEntryFromOption( PBYTE pPSStringBuff, PUI_BLOCK pUIBlock,
2931 PBYTE pOption, PINT pofsEntry )
2932{
2933 UINT uiLoop; // Local loop counter
2934 PBYTE pEntryName; // Current UI Entry name
2935 PUI_ENTRY pEntryRC = NULL; // Current entry return code
2936
2937 if (pofsEntry != NULL)
2938 {
2939 *pofsEntry = -1;
2940 }
2941
2942 for (uiLoop = 0 ; uiLoop < pUIBlock->usNumOfEntries ; uiLoop++)
2943 {
2944 pEntryName = pUIBlock->uiEntry[ uiLoop ].ofsOption + pPSStringBuff;
2945
2946 if (!strcmp( pOption, pEntryName ))
2947 {
2948 pEntryRC = &pUIBlock->uiEntry[ uiLoop ];
2949
2950 if (pofsEntry != NULL)
2951 {
2952 *pofsEntry = (INT) uiLoop;
2953 }
2954
2955 break;
2956 }
2957 }
2958
2959 return( pEntryRC );
2960}
2961
2962
2963
2964
2965
2966VOID ProcessCmdsAsUIs( )
2967{
2968 CHAR aUIString[ MAX_PSIZE ];
2969 CHAR aTempString[ MAX_PSIZE ];
2970 CHAR aUIDefString[ MAX_PSIZE ];
2971 BOOL bBlockProcessed;
2972 INT iBlockIndex;
2973 INT iStrLen;
2974 INT iCurrEntry;
2975 INT iIndex;
2976 PSZ pTransString;
2977 INT iVar;
2978 BOOL fMatchFound;
2979 BOOL fKeywordFound;
2980 PUI_BLOCK pUIBlock = desPpd.stUIList.pBlockList;
2981//USHORT usOrderDep = 0; NOTUSED
2982
2983 for (iIndex = 0 ; iIndex < (INT) desPpd.stUIList.usNumOfBlocks ; iIndex++)
2984 {
2985 INCREMENT_BLOCK_PTR( pUIBlock );
2986 }
2987
2988 strcpy( aUIDefString, "*Default" );
2989 for (iIndex = 0 ; iIndex < MAX_PREDEFINED ; iIndex++)
2990 {
2991 fMatchFound = FALSE;
2992 if (!strcmp( szPredefined[ iIndex ], "JCLResolution" ))
2993 {
2994 if (QueryBlockFromKeyword( &desPpd.stUIList, pbItemsBuffer,
2995 UINAME_RESOLUTION, NULL ) != NULL)
2996 {
2997 fMatchFound = TRUE;
2998 }
2999 }
3000
3001 if (QueryBlockFromKeyword( &desPpd.stUIList, pbItemsBuffer,
3002 szPredefined[ iIndex ], NULL ) == NULL &&
3003 fMatchFound == FALSE)
3004 {
3005 iCurrEntry = 0;
3006 aUIString[ 0 ] = '*';
3007 strcpy( &aUIString[ 1 ], szPredefined[ iIndex ] );
3008
3009 bBlockProcessed = FALSE;
3010 fKeywordFound = FALSE;
3011 fbseek( &fbIn, (long) 0, SEEK_SET );
3012 while (ScanParam( aUIString, pbPrBuffer ))
3013 {
3014 fKeywordFound = TRUE;
3015 iStrLen = 0;
3016 if (pUIBlock->ofsUIName == 0)
3017 {
3018 iBlockIndex = (INT) MatchKeywords( pbPrBuffer + 1, &desPpd.stUIList,
3019 pbItemsBuffer, TRUE );
3020
3021 if (iBlockIndex == -1)
3022 {
3023 pUIBlock->ofsUIName = pUIBlock->ofsUITransString = cbBuffout;
3024
3025 /*
3026 ** The default location is Document Setup. If not inserted,
3027 ** then the string is never sent out with the job.
3028 */
3029 pUIBlock->usUILocation = UI_ORDER_DOCSETUP;
3030
3031 /*
3032 ** If found, then this is a pre-defined feature (do not display
3033 ** in "Features" page).
3034 */
3035 pUIBlock->ucPanelID = UIP_PREDEF_FEATURE;
3036
3037 if (strcmp( szPredefined[ iIndex ], "SetResolution" ))
3038 {
3039 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
3040 szPredefined[ iIndex ],
3041 MAX_PSIZE,
3042 CSTR_INCLUDE_SLASH );
3043 }
3044 else
3045 {
3046 cbBuffout += CopyString( pbItemsBuffer + cbBuffout,
3047 &szPredefined[ iIndex ][ 3 ],
3048 MAX_PSIZE,
3049 CSTR_INCLUDE_SLASH );
3050 }
3051 }
3052 else
3053 {
3054 pUIBlock->ofsUIName = pUIBlock->ofsUITransString = iBlockIndex;
3055 }
3056 }
3057
3058 pTransString = (PSZ) pbPrBuffer;
3059 while (*pTransString != ' ' && *pTransString != '/')
3060 {
3061 pTransString++;
3062 }
3063
3064 if (*pTransString == '/')
3065 {
3066 *pTransString = 0;
3067 }
3068 else
3069 {
3070 pTransString = NULL;
3071 }
3072
3073 /*
3074 ** Copy the Option.
3075 */
3076 iStrLen = CopyString( pbItemsBuffer + cbBuffout,
3077 pbPrBuffer,
3078 80,
3079 CSTR_NORMAL );
3080 pUIBlock->uiEntry[ iCurrEntry ].ofsOption = cbBuffout;
3081
3082 cbBuffout += iStrLen;
3083
3084 if (pTransString != NULL)
3085 {
3086 iVar = CopyString( pbItemsBuffer + cbBuffout,
3087 pbPrBuffer + iStrLen,
3088 80,
3089 CSTR_NORMAL );
3090 pUIBlock->uiEntry[ iCurrEntry ].ofsTransString = cbBuffout;
3091 cbBuffout += iVar;
3092 iStrLen += iVar;
3093 }
3094 else
3095 {
3096 pUIBlock->uiEntry[ iCurrEntry ].ofsTransString =
3097 pUIBlock->uiEntry[ iCurrEntry ].ofsOption;
3098 }
3099
3100 /*
3101 ** skip the " character
3102 */
3103 do
3104 {
3105 iStrLen++;
3106 } while (*(pbPrBuffer + iStrLen - 1) != '"');
3107
3108 /*
3109 ** copies the string delimited by a blank or quote.
3110 */
3111 iStrLen = CopyInQuote( pbItemsBuffer + cbBuffout,
3112 pbPrBuffer + iStrLen, FALSE, NOCOMPRESS );
3113 pUIBlock->uiEntry[ iCurrEntry++ ].ofsValue = cbBuffout;
3114 cbBuffout += iStrLen;
3115
3116 pUIBlock->usNumOfEntries++;
3117 bBlockProcessed = TRUE;
3118 }
3119
3120 if (fKeywordFound == TRUE)
3121 {
3122 strcpy( &aUIDefString[ 8 ], szPredefined[ iIndex ] );
3123 fbseek( &fbIn, (long) 0, SEEK_SET );
3124
3125 if (ScanParam( aUIDefString, pbPrBuffer ))
3126 {
3127 iStrLen = 0;
3128 while (*(pbPrBuffer + iStrLen) == ':' ||
3129 *(pbPrBuffer + iStrLen) == ' ')
3130 {
3131 iStrLen++;
3132 }
3133
3134 CopyWord( aTempString, pbPrBuffer + iStrLen );
3135
3136 for (iBlockIndex = 0 ; iBlockIndex < pUIBlock->usNumOfEntries ;
3137 iBlockIndex++)
3138 {
3139 if (!strcmp( pUIBlock->uiEntry[ iBlockIndex ].ofsOption +
3140 pbItemsBuffer, aTempString ))
3141 {
3142 pUIBlock->usDefaultEntry = (USHORT) iBlockIndex;
3143 break;
3144 }
3145 }
3146 }
3147
3148 if (bBlockProcessed == TRUE)
3149 {
3150 desPpd.stUIList.usBlockListSize += QUERY_BLOCK_SIZE( pUIBlock );
3151 desPpd.stUIList.usNumOfBlocks++;
3152 INCREMENT_BLOCK_PTR( pUIBlock );
3153 }
3154 }
3155 }
3156 }
3157
3158 pUIBlock = desPpd.stUIList.pBlockList;
3159 for (iVar = 0 ; iVar < desPpd.stUIList.usNumOfBlocks ; iVar++)
3160 {
3161 pUIBlock->usOrderDep = (USHORT) iVar;
3162 INCREMENT_BLOCK_PTR( pUIBlock );
3163 }
3164}
3165
3166
3167
3168
3169INT CopyWord( PCHAR pDestn, PCHAR pSource )
3170{
3171 INT iStrLen = 0;
3172
3173 while (!isspace( *pSource ) && *pSource != ':')
3174 {
3175 *(pDestn++) = *(pSource++);
3176 iStrLen = 0;
3177 }
3178 *pDestn = 0;
3179
3180 return( iStrLen );
3181}
3182
3183
3184BOOL ParsePPDLang( PSZ pFileLine,
3185 PSZ pOutString
3186 )
3187{
3188 PSZ pColonChar;
3189 PSZ pParseChar;
3190 BOOL fRC = FALSE;
3191
3192 *pOutString = 0;
3193
3194 if ((pColonChar = strchr( pFileLine, ':' )) != NULL)
3195 {
3196 pParseChar = pColonChar + 1;
3197 while (*pParseChar == ' ')
3198 {
3199 pParseChar++;
3200 }
3201
3202 while (*pParseChar != '\n' && *pParseChar != ' ' && *pParseChar != 0)
3203 {
3204 *(pOutString++) = *(pParseChar++);
3205 }
3206 *pOutString = 0;
3207
3208 while (*pColonChar != 'L' && pColonChar >= pFileLine)
3209 {
3210 pColonChar--;
3211 }
3212 *pColonChar = 0;
3213
3214 fRC = TRUE;
3215 }
3216
3217 return( fRC );
3218}
3219
3220
3221
3222VOID VerifyUICList( )
3223{
3224 LONG lLoop;
3225 PUIC_BLOCK pUICBlock = desPpd.stUICList.puicBlockList;
3226
3227 for (lLoop = 0 ; lLoop < (LONG) desPpd.stUICList.usNumOfUICs ; lLoop++)
3228 {
3229 if (pUICBlock->uicEntry1.bOption == (UI_SEL) -1)
3230 {
3231 pUICBlock->uicEntry1.bOption = 0;
3232 }
3233
3234 if (pUICBlock->uicEntry2.bOption == (UI_SEL) -1)
3235 {
3236 pUICBlock->uicEntry2.bOption = 0;
3237 }
3238
3239 pUICBlock++;
3240 }
3241}
3242
3243
3244
3245
3246
3247
3248
3249//
3250// THE PUBLIC INTERFACE
3251//
3252
3253int Conv_PPD_Init(void)
3254{
3255 PUI_LIST pUIList = &desPpd.stUIList;
3256
3257 printf("initalize converter\n");
3258
3259 /*
3260 */
3261 memset( pUIList, 0, sizeof( UI_LIST ) );
3262 DosAllocMem( (PPVOID) &pUIList->pBlockList, 12288, /*4096,*/
3263 PAG_READ | PAG_WRITE | PAG_COMMIT );
3264 memset( pUIList->pBlockList, 0, 4096 );
3265
3266 memset( &desPpd.stUICList, 0, sizeof( UIC_LIST ) );
3267 DosAllocMem( (PPVOID) &desPpd.stUICList.puicBlockList, 12288,/*4096,*/
3268 PAG_READ | PAG_WRITE | PAG_COMMIT );
3269
3270
3271 BuildHashTable();
3272
3273 /*
3274 ** allocate memory for items buffer
3275 */
3276 if ((pbItemsBuffer = malloc(PRBUFSZ * 24)) == NULL)
3277 {
3278 RepError( err_cantopen, NULL );
3279 }
3280
3281 return 1;
3282}
3283
3284
3285/***************************************************************************
3286 *
3287 * FUNCTION NAME =
3288 *
3289 * DESCRIPTION = Function Mainline
3290 *
3291 *
3292 * INPUT =
3293 *
3294 * OUTPUT = NONE.
3295 *
3296 * RETURN-NORMAL = NONE.
3297 * RETURN-ERROR = NONE.
3298 *
3299 ************************************************************************* */
3300
3301int Conv_PPD_WritePPB( PSZ pszInFile, FILE *fhOut, PSZ pszDeviceName)
3302{
3303 int i;
3304 int iPPBCount;
3305 char *pc;
3306 UINT uiOutDirLen;
3307 CHAR szOutFile[CCHMAXPATH];
3308
3309 PUI_LIST pUIList = &desPpd.stUIList;
3310
3311 printf(".");
3312
3313 // check parameters
3314 if(pszInFile == NULL ||
3315 fhOut == NULL ||
3316 pszDeviceName == NULL)
3317 {
3318 return FALSE; // fail if not good
3319 }
3320
3321
3322 /*
3323 */
3324
3325 cbBuffout = 0;
3326
3327 if (!Openppd(pszInFile))
3328 {
3329 // Ignore PPD files that aren't found.
3330 RepWarning(err_cantopen,"ppd");
3331 return FALSE;
3332 }
3333
3334 printf(".");
3335
3336 sFormCount = 0; /* init for each ppd */
3337 /*
3338 ** Parse and create the PPD segment
3339 */
3340 BErrorWasDisplayed = FALSE;
3341 iShrinkage = 0;
3342 if (FormPpd())
3343 {
3344 strcpy( pszDeviceName, pbItemsBuffer + desPpd.desItems.ofsPrName );
3345
3346 printf(".");
3347
3348 if (!fhOut)
3349 {
3350 RepError( err_cantcreate, "ppb" );
3351 }
3352
3353 printf(".");
3354
3355 /*
3356 ** write the printer descriptor segment onto output file
3357 */
3358 if (fwrite( (char *) &desPpd,1,sizeof( desPpd ),fhOut) != sizeof(desPpd))
3359 {
3360 RepError( err_output, NULL );
3361 }
3362
3363 printf(".");
3364
3365 /*
3366 */
3367 if (pUIList->pBlockList != NULL)
3368 {
3369 fwrite( pUIList->pBlockList, 1, desPpd.stUIList.usBlockListSize,
3370 fhOut );
3371 memset( pUIList->pBlockList, 0, 4096 );
3372 }
3373 pUIList->usNumOfBlocks = 0;
3374 pUIList->usBlockListSize = 0;
3375
3376 if (desPpd.stUICList.usNumOfUICs > 0)
3377 {
3378 fwrite( desPpd.stUICList.puicBlockList, 1,
3379 desPpd.stUICList.usNumOfUICs * sizeof( UIC_BLOCK ), fhOut );
3380 memset( desPpd.stUICList.puicBlockList, 0, 4096 );
3381 }
3382
3383 printf(".");
3384
3385 /*
3386 ** write the items buffer which contain various names ,commands and
3387 ** dimensions lists
3388 */
3389 /* ftell( fhOut ); debug */
3390 if (fwrite( pbItemsBuffer, 1, cbBuffout, fhOut) != cbBuffout)
3391 {
3392 RepError( err_output1, NULL );
3393 }
3394 cbBuffout = 0;
3395 printf(".");
3396
3397 /*
3398 */
3399
3400 /*
3401 ** Close the ppb
3402 */
3403 }
3404 else
3405 return FALSE;
3406
3407 printf(".");
3408
3409 return TRUE;
3410}
3411
3412
3413void Conv_PPD_Done()
3414{
3415 // destroy
3416 /*
3417 ** Free the block list
3418 */
3419 DosFreeMem( desPpd.stUIList.pBlockList );
3420 DosFreeMem( desPpd.stUICList.puicBlockList );
3421}
3422
Note: See TracBrowser for help on using the repository browser.