source: trunk/gui/shared/PrManUtl.VRS@ 45

Last change on this file since 45 was 45, checked in by Alex Taylor, 12 years ago

Try to handle mismatched case in model name between DRV and PPD.

File size: 29.5 KB
Line 
1/*:VRX DriverIsInstalled
2*/
3/* Checks if a given print driver (without extension) is installed, and if so
4 * returns the path to the active files. Returns '' if the driver is not
5 * installed.
6 */
7DriverIsInstalled: PROCEDURE
8 ARG driver
9 PARSE VALUE VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER') WITH drv_path '00'x .
10 IF ( drv_path <> '') THEN
11 drv_path = STREAM( drv_path, 'C', 'QUERY EXISTS')
12RETURN drv_path
13
14
15/*:VRX GetDriverSource
16*/
17/* Figure out where to look for the PrinterPak driver files used as the install
18 * source. Preference is given to the local repository (PDR_DIR); if it's not
19 * there, we look in a couple of other places where it might have ended up.
20 * Note that we don't look for the actual installed driver files under \OS2\DLL;
21 * that logic is handled in LocateDriverFiles(), which calls this routine.
22 *
23 * Various global values are assumed to be set already:
24 * - globals.!prdrv: filespec of \OS2\INSTALL\PRDRV.LST
25 * - globals.!repository: value indicated by PM_INSTALL->PDR_DIR in OS2.INI
26 *
27 * Arguments: The print driver name without path or extension
28 *
29 * Returns the path, or '' if not found. Also, 'pmdx' will be 0-9 if the
30 * driver is in the repository (indicating the repository subdirectory), or
31 * '' if the driver is not in the repository.
32 */
33GetDriverSource: PROCEDURE EXPOSE globals. pmdx
34 ARG driver
35 IF driver == '' THEN RETURN ''
36
37 drv_file = ''
38 IF globals.!repository <> '' THEN DO
39
40 /* See if the driver is defined in the local repository. (This is the
41 * directory where installable printer drivers are kept. OS/2 gets them
42 * from here when you select 'Printer driver included with OS/2'.)
43 */
44 pmdx = GetDriverPMDD( driver, globals.!prdrv )
45 IF pmdx == '' THEN DO
46 /* Hmm, the driver isn't listed in PRDRV.LST. Let's check to see if
47 * it's in the default repository location anyway.
48 */
49 IF WORDPOS( driver, 'ECUPS ECUPS-HP PSPRINT PSPRINT2') > 0 THEN
50 pmdx = '9'
51 ELSE
52 pmdx = '0'
53 drv_file = STREAM( globals.!repository'\PMDD_'pmdx'\'driver'.DRV', 'C', 'QUERY EXISTS')
54 IF drv_file <> '' THEN DO
55 /* We found the driver in the repository, even though it isn't
56 * defined as such. So let's add the proper definition to
57 * PRDRV.LST now.
58 */
59 CALL LINEOUT globals.!prdrv, LEFT( driver'.DRV', 14 ) pmdx ||,
60 ' (added automatically)'
61 CALL LINEOUT globals.!prdrv
62 END
63 ELSE
64 pmdx = ''
65 END
66 ELSE DO
67 /* The driver is listed; now make sure it's actually there.
68 */
69 drv_file = STREAM( globals.!repository'\PMDD_'pmdx'\'driver'.DRV', 'C', 'QUERY EXISTS')
70 END
71 END
72
73 IF drv_file == '' THEN DO
74 CALL LINEOUT globals.!log1, 'Driver' driver 'is not in the local repository.'
75 /* If the driver really isn't in the repository, there are a couple of
76 * other places that various install utilities might have put it...
77 */
78 PARSE VALUE VRGetIni('PM_INSTALL', driver'_DIR', 'USER') WITH drvr_dir '00'x .
79 IF drvr_dir == '' THEN
80 PARSE VALUE VRGetIni('InstPDR', 'PATH_TO_'driver, 'USER') WITH drvr_dir '00'x .
81 IF drvr_dir <> '' THEN DO
82 drv_file = drvr_dir'\'driver'.DRV'
83 CALL LINEOUT globals.!log1, 'Found driver in' drvr_dir'.'
84 END
85 END
86
87RETURN drv_file
88
89
90/*:VRX GetDriverPMDD
91*/
92/* Check to see which repository directory the specified driver resides in.
93 * Returns the number suffix of the PMDD_* subdirectory name, or '' if either
94 * the driver or the index file could not be located.
95 *
96 * Arguments: The print driver name without path or extension
97 */
98GetDriverPMDD: PROCEDURE
99 PARSE ARG driver, prdrv_lst
100
101 IF prdrv_lst <> '' THEN DO
102 CALL LINEIN prdrv_lst, 1, 0
103 DO WHILE LINES( prdrv_lst ) > 0
104 PARSE VALUE LINEIN( prdrv_lst ) WITH (driver)'.DRV' pmdx .
105 IF pmdx <> '' THEN LEAVE
106 END
107 CALL STREAM prdrv_lst, 'C', 'CLOSE'
108 END
109 ELSE pmdx = ''
110
111RETURN pmdx
112
113
114/*:VRX LocateDriverFiles
115*/
116/* Locates the source files for a PostScript-based driver that will be required in
117 * order to import a PPD using PIN. Not to be used with non-PostScript drivers,
118 * since it will fail if PIN or PPDENC are not found.
119 *
120 * Arguments: The print driver name without path or extension
121 *
122 * Returns:
123 * 0 - Driver files not found.
124 * 1 - Driver files found, path saved in 'driver_path'; 'driver_repo' will be 1
125 * if the driver is 'shipped' (i.e. defined in PRDRV.LST) or 0 otherwise.
126 * 2 - Only found installed driver files in (\OS2\DLL\xxx, saved in 'driver_path');
127 * will need to copy them somewhere for future installs.
128 */
129LocateDriverFiles: PROCEDURE EXPOSE globals. driver_path driver_repo
130 ARG driver
131 IF driver == '' THEN driver = 'PSCRIPT'
132
133 CALL LINEOUT globals.!log1, 'Looking for' driver 'files'
134
135 mustcopy = 0
136 driver_path = GetDriverSource( driver )
137
138 IF driver_path == '' THEN DO
139 /* No source found. We'll have to try copying the actual installed
140 * driver files from under \OS2\DLL.
141 */
142 CALL LINEOUT globals.!log1, 'Driver source not found. Trying installed driver.'
143 PARSE VALUE VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER') WITH drv_used '00'x .
144 IF ( drv_used <> '') & VRFileExists( drv_used ) THEN
145 driver_path = drv_used
146 END
147 IF driver_path <> '' THEN DO
148 srcdir = VRParseFilePath( driver_path, 'DP')
149 pin = STREAM( srcdir'\PIN.EXE', 'C', 'QUERY EXISTS')
150 ppdenc = STREAM( srcdir'\PPDENC.EXE', 'C', 'QUERY EXISTS')
151 /* TODO should we check for all the REQUIREDDRIVER FILES as well? */
152 END
153
154 IF pmdx == '' THEN
155 driver_repo = 0
156 ELSE
157 driver_repo = 1
158
159 /* Driver (or one of its required files) was not found.
160 */
161 IF ( driver_path == '') | ( pin == '') | ( ppdenc == '') | ,
162 ( VerifyDriverEAs( driver_path ) == 0 ) THEN
163 DO
164 CALL LINEOUT globals.!log1, ' - Missing required driver files.'
165 RETURN 0
166 END
167
168 IF mustcopy THEN RETURN 2
169RETURN 1
170
171
172/*:VRX VerifyDriverEAs
173*/
174/* Make sure the driver has its extended attributes. If not, look for an
175 * accompanying .EA or .EA_ file, and join it to the driver.
176 */
177VerifyDriverEAs: PROCEDURE EXPOSE globals.
178 PARSE ARG driver
179 eas.0 = 0
180 CALL SysQueryEAList driver, 'eas.'
181 IF eas.0 == 0 THEN DO
182 ea_file = SUBSTR( driver, 1, LASTPOS('.', driver )) || 'EA'
183 IF STREAM( ea_file, 'C', 'QUERY EXISTS') == '' THEN
184 ea_file = ea_file || '_'
185 IF STREAM( ea_file, 'C', 'QUERY EXISTS') == '' THEN
186 RETURN 0
187
188 ADDRESS CMD '@UNLOCK' driver '2>NUL 1>NUL'
189 ADDRESS CMD '@EAUTIL' driver ea_file '/j /p 2>NUL 1>NUL'
190 END
191RETURN 1
192
193
194/*:VRX BldLevelVersion
195*/
196/* Parse the revision (version) number from a BLDLEVEL string
197 */
198BldLevelVersion: PROCEDURE EXPOSE globals.
199 ARG module
200 revision = ''
201
202 _nq = RXQUEUE('CREATE')
203 _oq = RXQUEUE('SET', _nq )
204
205 ADDRESS CMD '@bldlevel' module '2>&1 | RXQUEUE' _nq
206 DO QUEUED()
207 PARSE PULL _blline
208 IF LEFT( _blline, 9 ) == 'Revision:' THEN DO
209 PARSE VAR _blline 'Revision:' revision .
210 LEAVE
211 END
212 END
213
214 CALL RXQUEUE 'SET', _oq
215 CALL RXQUEUE 'DELETE', _nq
216
217 IF revision == '' THEN revision = '-'
218
219RETURN revision
220
221
222/*:VRX CopyPrinterPak
223*/
224/* Copies a printerpak driver and all its dependent files from one directory
225 * to another.
226 *
227 * driver - The fully-qualified filename of the printerpak .DRV
228 * newdrvdir - The directory where the files will be copied; must exist
229 *
230 * Returns: 1 on success, 0 on failure
231 */
232CopyPrinterPak: PROCEDURE EXPOSE globals.
233 PARSE ARG driver, newdrvdir
234
235 drv_dir = VRParseFilePath( driver, 'DP')
236 drv_name = VRParseFilePath( driver, 'NE')
237 IF drv_dir == '' THEN RETURN 0
238
239 IF VerifyDriverEAs( driver ) == 0 THEN RETURN 0
240
241 CALL LINEOUT globals.!log1, 'Copying driver files from' drv_dir 'to' newdrvdir'...'
242
243 /* Read the list of required driver files from the EAs, and copy them
244 * all to the target directory.
245 */
246 IF SysGetEA( driver, 'REQUIREDDRIVERFILES', 'reqfiles') == 0 THEN DO
247 PARSE VAR reqfiles 5 filelist
248 filelist = TRANSLATE( filelist, ' ', ',')
249 DO i = 1 TO WORDS( filelist )
250 copyfile = drv_dir'\' || WORD( filelist, i )
251 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
252 CALL LINEOUT globals.!log1, ' -' copyfile '(REQUIRED):' ok
253 END
254 DROP copyfile
255 DROP filelist
256 END
257 ELSE RETURN 0
258
259 /* If there are optional files defined as well, try to copy those also.
260 */
261 IF SysGetEA( driver, 'OPTIONALDRIVERFILES', 'reqfiles') == 0 THEN DO
262 PARSE VAR reqfiles 5 filelist
263 filelist = TRANSLATE( filelist, ' ', ',')
264 DO i = 1 TO WORDS( filelist )
265 copyfile = drv_dir'\' || WORD( filelist, i )
266 IF STREAM( copyfile, 'C', 'QUERY EXISTS') == '' THEN ITERATE
267 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
268 CALL LINEOUT globals.!log1, ' -' copyfile '(OPTIONAL):' ok
269 END
270 DROP copyfile
271 DROP filelist
272 END
273
274 /* If AUXPRINT.PAK exists, copy it as well */
275 copyfile = drv_dir'\AUXPRINT.PAK'
276 IF STREAM( copyfile, 'C', 'QUERY EXISTS') <> '' THEN DO
277 ok = VRCopyFile( copyfile, newdrvdir'\AUXPRINT.PAK'
278 CALL LINEOUT globals.!log1, ' -' copyfile ':' ok
279 END
280
281 /* Create an EA file if necessary */
282 eafile = VRParseFilePath( driver, 'N') || '.EA'
283 IF VRFileExists( newdrvdir'\'eafile ) THEN
284 CALL VRDeleteFile newdrvdir'\'eafile
285 ADDRESS CMD '@EAUTIL' newdrvdir'\'drv_name newdrvdir'\'eafile '/s /p 2>NUL 1>NUL'
286
287RETURN 1
288
289
290/*:VRX PrinterExistsInDRV
291*/
292/* Determine if the specified PrinterPak driver already contains support
293 * for the specified printer model.
294 *
295 * If so, return the name of the model as found in the driver (necessary in
296 * order to make sure the correct case is retained, which may be different
297 * from what was requested). Otherwise return ''.
298 */
299PrinterExistsInDRV: PROCEDURE EXPOSE globals.
300 PARSE UPPER ARG driver_name, printer_name
301 printer_name = TRANSLATE( printer_name, '_', '.')
302
303 printer_drv = globals.!os2dir'\DLL\'driver_name'\'driver_name'.DRV'
304 /* ?? TODO: install driver_name if not found (prompt first) ?? */
305
306 IF SysGetEA( printer_drv, '.EXPAND', 'exist_ea') <> 0 THEN RETURN 0
307 PARSE VAR exist_ea 1 _eatype 3 .
308 IF C2X( _eatype ) <> 'FDFF' THEN RETURN 0
309
310 PARSE VAR exist_ea 3 _ealen 5 exist_models
311 total_len = C2D( REVERSE( _ealen ))
312
313 /* The variable exist_models now contains a null-separated list of printer
314 * models supported by the driver (including those from previously-imported
315 * PPD files). Next we check each one against our requested printer name.
316 */
317 start = 1
318 found = ''
319 DO WHILE ( found == 0 ) & ( start < total_len )
320 _strend = POS('0'x, exist_models, start )
321 IF _strend == 0 THEN LEAVE
322 _model = SUBSTR( exist_models, start, _strend - start )
323 IF TRANSLATE( _model ) == printer_name THEN
324 found = _model
325 ELSE
326 start = _strend + 1
327 END
328
329RETURN found
330
331
332/*:VRX CreateDriverList
333*/
334/* Generate a driver listfile from the .EXPAND EA
335 */
336CreateDriverList: PROCEDURE EXPOSE globals.
337 ARG driver, listfile
338
339 IF STREAM( listfile, 'C', 'QUERY EXISTS') <> '' THEN
340 CALL SysFileDelete listfile
341
342 drv_name = FILESPEC('NAME', driver )
343 IF SysGetEA( driver, '.EXPAND', 'eaval') == 0 THEN DO
344 PARSE VAR eaval 3 ealen 5 models
345 offs = 1
346 datalen = C2D( REVERSE( ealen ))
347 DO WHILE offs <= datalen
348 start = SUBSTR( models, offs )
349 inc = POS('00'x, start )
350 IF inc > 1 THEN DO
351 current_name = STRIP( SUBSTR( start, 1, inc-1 ))
352 CALL LINEOUT listfile, current_name':' current_name '('drv_name')'
353 END
354 offs = offs + inc
355 END
356 CALL LINEOUT listfile
357 CALL LINEOUT globals.!log1, 'Created driver list' listfile 'for' driver'.'
358 END
359 ELSE
360 CALL LINEOUT globals.!log1, 'No drivers found in' driver '(missing .EXPAND extended attribute?)'
361
362RETURN 1
363
364
365/*:VRX AddPort_CUPS
366*/
367/* Adds a new CUPS port. Returns 0 on full success, 1 if the port was created
368 * but could not be configured, and an OS/2 or PM error code otherwise.
369 */
370AddPort_CUPS: PROCEDURE EXPOSE globals.
371 PARSE ARG portname, hostname, queuename
372 CALL LINEOUT globals.!log1, 'Creating new port' portname
373 ADDRESS CMD '@cupsport' portname hostname queuename '>>' globals.!log2
374 IF rc == 1 THEN DO
375 CALL VRSetIni 'PM_'portname, 'INITIALIZATION', hostname'#'queuename||'00'x, 'SYSTEM', 'NoClose'
376 CALL VRSetIni 'PM_'portname, 'DESCRIPTION', hostname':'queuename||'00'x, 'SYSTEM'
377 END
378RETURN rc
379
380
381/*:VRX DeletePort
382*/
383/* Deletes a printer port (any type).
384 */
385DeletePort: PROCEDURE EXPOSE globals.
386 PARSE ARG portname
387 CALL SysIni 'SYSTEM', 'PM_'portname, 'DELETE:'
388 CALL SysIni 'SYSTEM', 'PM_SPOOLER_PORT', portname, 'DELETE:'
389RETURN 1
390
391
392/*:VRX GetNextPortName
393*/
394/* Get the next unique (non-existing) port name for the specified port driver.
395 */
396GetNextPortName: PROCEDURE
397 ARG portdrv
398
399 maxports = 64 /* should be smarter about this if possible */
400 exists = 1
401 x = 0
402 DO WHILE ( x < maxports ) & ( exists == 1 )
403 x = x + 1
404 portname = portdrv || x
405 nextport = SysIni('SYSTEM', 'PM_SPOOLER_PORT', portname )
406 IF LEFT( nextport, 6 ) == 'ERROR:' THEN exists = 0
407 END
408 IF exists == 1 THEN
409 portname = ''
410
411RETURN portname
412
413
414/*:VRX GetPortDrivers
415*/
416/* Get the list of currently-installed port drivers. NOTE: we exclude LPRPDRVR
417 * from this list, because it has to be managed via the TCP/IP configuration
418 * program.
419 */
420GetPortDrivers: PROCEDURE EXPOSE portdrivers.
421 ok = SysIni('SYSTEM', 'PM_PORT_DRIVER', 'ALL:', 'installed.')
422 IF LEFT( ok, 6 ) == 'ERROR:' THEN RETURN 0
423 count = 0
424 DO i = 1 TO installed.0
425 IF installed.i = 'LPRPDRVR' THEN ITERATE
426 fullpath = STRIP( SysIni('SYSTEM', 'PM_PORT_DRIVER', installed.i ), 'T', '00'x )
427 IF LEFT( fullpath, 6 ) == 'ERROR:' THEN fullpath = ''
428 fullpath = STREAM( fullpath , 'C', 'QUERY EXISTS')
429 count = count + 1
430 portdrivers.count = installed.i || ' ' || fullpath
431 END
432 portdrivers.0 = count
433RETURN portdrivers.0
434
435
436/*:VRX GetQueueName
437*/
438/* Generate a unique queue name from the specified printer name.
439 */
440GetQueueName: PROCEDURE
441 ARG queuename
442
443 DO UNTIL badchar = 0
444 badchar = VERIFY( queuename, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789 ')
445 IF badchar > 0 THEN
446 queuename = OVERLAY(' ', queuename, badchar, 1 )
447 END
448 queuename = LEFT( SPACE( queuename, 0 ), 8 )
449
450 tail = 0
451 PARSE VALUE VRGetIni('PM_SPOOLER', 'DIR', 'SYSTEM') WITH spldir ';' .
452 DO WHILE VRFileExists( spldir'\'queuename ) == 1
453 tail = tail + 1
454 queuename = STRIP( LEFT( queuename, 8 - LENGTH( tail ))) || tail
455 END
456
457RETURN queuename
458
459
460/*:VRX InstallPortDriver
461*/
462/* Installs a new port driver.
463 *
464 * Returns: 0 on success, 1 on error
465 */
466InstallPortDriver: PROCEDURE EXPOSE globals.
467 ARG new_pdr
468 filename = VRParseFileName( new_pdr, 'NE')
469 IF filename == '' THEN RETURN
470 installed_pdr = TRANSLATE( globals.!os2dir'\DLL\'filename )
471 IF installed_pdr <> new_pdr THEN DO
472 ok = VRCopyFile( new_pdr, installed_pdr )
473 IF ok == 0 THEN RETURN 1
474 /* Try to copy any optional files as well */
475 IF SysGetEA( new_pdr, 'OPTIONALDRIVERFILES', 'reqfiles') == 0 THEN DO
476 drv_dir = VRParseFilePath( new_pdr, 'DP')
477 PARSE VAR reqfiles 5 filelist
478 filelist = TRANSLATE( filelist, ' ', ',')
479 DO i = 1 TO WORDS( filelist )
480 copyfile = drv_dir'\' || WORD( filelist, i )
481 IF STREAM( copyfile, 'C', 'QUERY EXISTS') == '' THEN ITERATE
482 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
483 /*CALL LINEOUT globals.!log1, ' -' copyfile '(OPTIONAL):' ok*/
484 END
485 END
486 END
487
488 key = VRParseFileName( installed_pdr, 'N')
489 CALL VRSetIni 'PM_PORT_DRIVER', key, installed_pdr||'00'x, 'SYSTEM'
490RETURN 0
491
492
493/*:VRX InstallPrintDriver
494*/
495/* 'Installs' (that is to say, registers with the spooler) an OS printer
496 * device driver/model. Installs the corresponding printerpak driver if
497 * necessary.
498 *
499 * driver - The name of the printerpak driver (without path or extension)
500 * driverfull - The fully-qualified filename of the printerpak driver
501 * model - The printer make/model name used by the driver
502 *
503 * Returns: 0 on success, 1 on error
504 */
505InstallPrintDriver: PROCEDURE EXPOSE globals.
506 PARSE ARG driver, driverfull, model
507
508 ok = 0
509 targetdir = globals.!os2dir'\DLL\'driver
510 targetdrv = targetdir'\'driver'.DRV'
511 CALL LINEOUT globals.!log1, 'Installing' driver'.'model 'from' driverfull '(target' targetdrv')'
512
513 IF ( VRFileExists( targetdrv ) == 0 ) THEN DO
514 CALL VRMkDir targetdir
515 r = CopyPrinterPak( driverfull, targetdir )
516 IF r <> 1 THEN ok = 1
517 END
518 IF ok == 0 THEN DO
519 IF VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER') <> targetdrv THEN
520 CALL VRSetIni 'PM_DEVICE_DRIVERS', driver, targetdrv||'00'x, 'USER'
521 CALL VRSetIni 'PM_SPOOLER_DD', driver'.'model, driver'.DRV;;;'||'00'x, 'SYSTEM'
522 END
523RETURN ok
524
525/*:VRX DeletePrintDriver
526*/
527/* Removes (that is to say, de-registers with the spooler) a PM printer
528 * device driver/model.
529 *
530 * driver - The name of the printerpak driver (without path or extension)
531 * model - The printer make/model name used by the driver
532 *
533 * Returns: 0 on success, 1 on error
534 */
535DeletePrintDriver: PROCEDURE EXPOSE globals.
536 PARSE ARG driver, model
537
538 ok = VRDelIni('PM_SPOOLER_DD', driver'.'model, 'SYSTEM')
539RETURN ok
540
541/*:VRX CreatePrinterObject
542*/
543/* Create the specified printer using SysCreateObject (this should create the
544 * queue automatically).
545 *
546 * Returns: 0 on success or non-zero return code on error.
547 */
548CreatePrinterObject: PROCEDURE EXPOSE globals.
549 PARSE ARG driver, model, portname, queuename, printername
550
551 CALL LINEOUT globals.!log1, 'Creating new printer:' printername '('queuename')'
552 ok = RPUPrinterCreate( printername, queuename, portname, driver'.'model )
553RETURN ok
554
555/*:VRX GetNameFromPPD
556*/
557GetNameFromPPD: PROCEDURE
558 ARG ppd_file
559
560 IF STREAM( ppd_file, 'C', 'QUERY EXISTS') == '' THEN RETURN ''
561 nickname = ''
562 IF VRParseFilePath( ppd_file, 'E') == 'GZ' THEN DO
563 nq = RXQUEUE('CREATE')
564 oq = RXQUEUE('SET', nq )
565 ADDRESS CMD '@gzip -c -d' ppd_file '| RXQUEUE' nq
566 DO QUEUED()
567 PARSE PULL line
568 line = STRIP( line )
569 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
570 PARSE VAR line . ':' _nick '0D'x .
571 nickname = STRIP( _nick )
572 nickname = STRIP( nickname, 'B', '"')
573 LEAVE
574 END
575 END
576 CALL RXQUEUE 'SET', oq
577 CALL RXQUEUE 'DELETE', nq
578 END
579 ELSE DO
580 CALL LINEIN ppd_file, 1, 0
581 DO WHILE LINES( ppd_file ) <> 0
582 line = STRIP( LINEIN( ppd_file ))
583 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
584 PARSE VAR line . ':' _nick '0D'x .
585 nickname = STRIP( _nick )
586 nickname = STRIP( nickname, 'B', '"')
587 LEAVE
588 END
589 END
590 CALL STREAM ppd_file, 'C', 'CLOSE'
591 END
592
593RETURN nickname
594
595/*:VRX CleanPPD
596*/
597/* Clean out lines from Gutenprint and Foomatic PPD files that are known to
598 * cause problems when importing with PIN. (Partially based on work by Paul
599 * Smedley and Peter Brown).
600 */
601CleanPPD: PROCEDURE
602 PARSE ARG in_ppd, logfile
603 IF logfile <> '' THEN
604 logfile = STREAM( logfile, 'C', 'QUERY EXISTS')
605
606 out_ppd = VRParseFilePath( in_ppd, 'DPN') || '.TMP'
607 IF STREAM( out_ppd, 'C', 'QUERY EXISTS') \= '' THEN
608 CALL SysFileDelete out_ppd
609
610 IF logfile <> '' THEN
611 CALL CHAROUT logfile, 'Doing cleanup on' in_ppd '...'
612
613 skip_next = 0
614 DO WHILE LINES( in_ppd ) \= 0
615 line = LINEIN( in_ppd )
616 SELECT
617 WHEN skip_next == 1 THEN DO
618 line = STRIP( TRANSLATE( line ))
619 IF line == '*END' THEN skip_next = 0
620 END
621 WHEN LEFT( line, 11 ) == '*StpDefault' THEN NOP
622 WHEN LEFT( line, 7 ) == '*StpStp' THEN NOP
623 WHEN LEFT( line, 18 ) == '*StpResolutionMap:' THEN NOP
624 WHEN LEFT( line, 14 ) == '*OPOptionHints' THEN NOP
625 WHEN LEFT( line, 4 ) == '*da.' THEN NOP
626 WHEN LEFT( line, 4 ) == '*de.' THEN NOP
627 WHEN LEFT( line, 4 ) == '*es.' THEN NOP
628 WHEN LEFT( line, 4 ) == '*fi.' THEN NOP
629 WHEN LEFT( line, 4 ) == '*fr.' THEN NOP
630 WHEN LEFT( line, 4 ) == '*it.' THEN NOP
631 WHEN LEFT( line, 4 ) == '*ja.' THEN NOP
632 WHEN LEFT( line, 4 ) == '*ko.' THEN NOP
633 WHEN LEFT( line, 4 ) == '*nb.' THEN NOP
634 WHEN LEFT( line, 4 ) == '*nl.' THEN NOP
635 WHEN LEFT( line, 4 ) == '*pt.' THEN NOP
636 WHEN LEFT( line, 4 ) == '*sv.' THEN NOP
637 WHEN LEFT( line, 7 ) == '*zh_CN.' THEN NOP
638 WHEN LEFT( line, 7 ) == '*zh_TW.' THEN NOP
639 WHEN LEFT( line, 9 ) == '*Foomatic' THEN DO
640 line = STRIP( line )
641 IF RIGHT( line, 2 ) == '&&' THEN skip_next = 1
642 END
643 OTHERWISE DO
644 CALL LINEOUT out_ppd, line
645 skip_next = 0
646 END
647 END
648 END
649 CALL STREAM in_ppd, 'C', 'CLOSE'
650 CALL STREAM out_ppd, 'C', 'CLOSE'
651
652 ok = VRCopyFile( out_ppd, in_ppd )
653 IF logfile <> '' THEN DO
654 IF ok == 1 THEN
655 CALL LINEOUT logfile, 'OK'
656 ELSE DO
657 CALL LINEOUT logfile, 'Failed!'
658 CALL LINEOUT logfile, ' ->' VRError()
659 END
660 CALL LINEOUT logfile, ''
661 END
662 CALL SysFileDelete out_ppd
663
664RETURN
665
666/*:VRX MatchPrinterModel
667*/
668/* Find a set of printers supported by the OS/2 driver which mostly closely
669 * match the given name.
670 */
671MatchPrinterModel: PROCEDURE EXPOSE globals. models.
672 PARSE UPPER ARG driver_name, printer_name
673 printer_name = TRANSLATE( printer_name, '_', '.')
674 printer_drv = globals.!os2dir'\DLL\'driver_name'\'driver_name'.DRV'
675 models.0 = 0
676
677 IF SysGetEA( printer_drv, '.EXPAND', 'exist_ea') <> 0 THEN RETURN 0
678 PARSE VAR exist_ea 1 _eatype 3 .
679 IF C2X( _eatype ) <> 'FDFF' THEN RETURN 0
680
681 PARSE VAR exist_ea 3 _ealen 5 exist_models
682 total_len = C2D( REVERSE( _ealen ))
683
684 /* The variable exist_models now contains a null-separated list of printer
685 * models supported by the driver (including those from previously-imported
686 * PPD files). Next we check each one against our requested printer name.
687 */
688 start = 1
689 count = 0
690 best = 0
691 DO WHILE start < total_len
692 _strend = POS('0'x, exist_models, start )
693 IF _strend == 0 THEN LEAVE
694 _model = TRANSLATE( SUBSTR( exist_models, start, _strend - start ))
695 _model = TRANSLATE( _model, ' ', '-')
696 _comp = COMPARE( _model, printer_name )
697 IF WORD( _model, 1 ) == WORD( printer_name, 1 ) THEN DO
698 count = count + 1
699 IF _comp == 0 THEN DO
700 _comp = 9999
701 best = count
702 END
703 ELSE IF ( best == 0 ) & ( _comp > LENGTH( printer_name )) THEN
704 best = count
705/*
706 models.count = RIGHT( _comp, 4, '0') SUBSTR( exist_models, start, _strend - start )
707*/
708 models.count = SUBSTR( exist_models, start, _strend - start )
709 END
710 start = _strend + 1
711 END
712 models.0 = count
713
714/*
715 CALL SysStemSort 'models.', 'D', 'I',,, 1, 4
716 DO i = 1 TO count
717 models.i = SUBWORD( models.i, 2 )
718 END
719*/
720RETURN best
721
722
723/*:VRX CheckWritablePath
724*/
725CheckWritablePath: PROCEDURE EXPOSE globals.
726 ARG path
727
728 /* Make sure path exists & is a directory */
729 IF \VRIsDir( path ) THEN RETURN 1
730
731 /* Make sure the drive is accessible */
732 di = SysDriveInfo( VRParseFilePath( path, 'DP'))
733 IF di == '' THEN RETURN 2
734
735 /* Make sure the drive has a supported filesystem */
736 fs = SysFileSystemType( prdrv )
737 IF WORDPOS( fs, 'HPFS JFS FAT FAT32') == 0 THEN RETURN 3
738
739RETURN 0
740
741
742/*:VRX QueryAvailableDrivers
743*/
744/* Determine which of our supported PrinterPak drivers are currently available.
745 */
746QueryAvailableDrivers: PROCEDURE EXPOSE globals. drv_list.
747 drv_list.0 = 0
748
749 test_drivers = 'ECUPS ECUPS-HP PSPRINT'
750 DO i = 1 TO WORDS( test_drivers )
751 driver = WORD( test_drivers, i )
752 ok = GetDriverSource( driver )
753 IF ok == '' THEN
754 ok = VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER')
755 IF ok <> '' THEN
756 CALL SysStemInsert 'drv_list.', drv_list.0+1, driver
757 END
758
759RETURN drv_list.0
760
761
762/*:VRX UpdatePrDesc
763*/
764UpdatePrDesc: PROCEDURE EXPOSE globals.
765 ARG driver, fqn
766
767 IF globals.!prdesc == '' THEN RETURN 1
768
769 ok = RPUEnumModels( fqn, 'newdevs.')
770 IF ok == 0 THEN RETURN 2
771
772 _count = 0
773 CALL LINEIN globals.!prdesc, 1, 0
774 DO WHILE LINES( globals.!prdesc )
775 _next = LINEIN( globals.!prdesc )
776 PARSE UPPER VAR _next WITH . ':' . '('_prdrv')' .
777 IF _prdrv == driver THEN ITERATE
778 _count = _count + 1
779 prdefs.count = _next
780 END
781 CALL STREAM globals.!prdesc, 'C', 'CLOSE'
782
783 DO i = 1 TO devs.0
784 _count = _count + 1
785 prdefs._count = newdevs.i':' newdevs.i '('driver')'
786 END
787 prdefs.0 = count
788
789 CALL VRSortStem 'prdefs.'
790
791 _prdir = VRParseFileName( globals.!prdesc, 'DP')
792 CALL VRCopyFile globals.!prdesc, _prdir'\PRDESC.BAK'
793 CALL VRDeleteFile globals.!prdesc
794 DO i = 1 TO prdefs.0
795 CALL LINEOUT globals.!prdesc, prdefs.i
796 END
797 CALL LINEOUT globals.!prdesc
798
799RETURN 0
800
801
802/*:VRX NLSGetMessage
803*/
804/*
805 * Gets the message text associated with the given message number from the
806 * current language file.
807 */
808NLSGetMessage: PROCEDURE EXPOSE globals.
809 PARSE ARG msgnum, .
810 args = ARG()
811
812 msgfile = globals.!messages
813 IF msgnum == '' THEN RETURN ''
814
815 sub_parms = ''
816 DO i = 2 TO args
817 sub_parms = sub_parms', "'ARG( i )'"'
818 END
819
820 INTERPRET 'msgfromfile = SysGetMessage( msgnum, msgfile' sub_parms ')'
821
822 PARSE VAR msgfromfile message '0D'x .
823 IF SUBSTR( message, 1, 4 ) == 'SYS0' THEN message = ''
824
825RETURN message
826
827
828/*:VRX NLSSetText
829*/
830/*
831 * Sets the specified property of the specified control to the specified
832 * message text.
833 */
834NLSSetText: PROCEDURE EXPOSE globals.
835 PARSE ARG control, property, message, substitution
836 args = ARG()
837
838 success = 1
839 IF args < 4 THEN
840 text = NLSGetMessage( message )
841 ELSE DO
842 sub_parms = ''
843 DO i = 4 TO args
844 sub_parms = sub_parms '"'|| ARG( i ) ||'",'
845 END
846 sub_parms = STRIP( sub_parms, 'T', ',')
847 INTERPRET 'text = NLSGetMessage( message, 'sub_parms')'
848 END
849
850 IF text == '' THEN success = 0
851 ELSE CALL VRSet control, property, text
852
853RETURN success
854
855/*:VRX StringTokenize
856*/
857StringTokenize:
858 PARSE ARG string, separator, __stem
859 CALL __StringTokenize string, separator, __stem
860 DROP __stem
861RETURN
862
863/*:VRX __StringTokenize
864*/
865__StringTokenize: PROCEDURE EXPOSE (__stem)
866 PARSE ARG string, separator, tokens
867
868 /* Note: this differs slightly from my usual implementation in that
869 * each token is STRIPped of leading and trailing spaces.
870 */
871
872 IF ( string = '') THEN RETURN string
873 IF ( separator = '') THEN separator = ' '
874
875 i = 0
876 CALL VALUE tokens || '0', i
877 DO WHILE LENGTH( string ) > 0
878 x = 1
879 y = POS( separator, string, x )
880 IF y > 0 THEN DO
881 current = SUBSTR( string, 1, y-1 )
882 x = y + 1
883 i = i + 1
884 CALL VALUE tokens || 'i', STRIP( current )
885 END
886 ELSE DO
887 current = STRIP( string, 'B', separator )
888 i = i + 1
889 CALL VALUE tokens || 'i', STRIP( current )
890 x = LENGTH( string ) + 1
891 END
892 string = SUBSTR( string, x )
893 END
894 CALL VALUE tokens || '0', i
895
896RETURN
897
Note: See TracBrowser for help on using the repository browser.