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

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

Support installing a new driver.model directly. Keyboard navigation improved. Some bug fixes. (Now requires VROBJEX 1.1.2 or later.)

File size: 28.7 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 IF drv_dir == '' THEN RETURN 0
237
238 IF VerifyDriverEAs( driver ) == 0 THEN RETURN 0
239
240 CALL LINEOUT globals.!log1, 'Copying driver files from' drv_dir 'to' newdrvdir'...'
241
242 /* Read the list of required driver files from the EAs, and copy them
243 * all to the target directory.
244 */
245 IF SysGetEA( driver, 'REQUIREDDRIVERFILES', 'reqfiles') == 0 THEN DO
246 PARSE VAR reqfiles 5 filelist
247 filelist = TRANSLATE( filelist, ' ', ',')
248 DO i = 1 TO WORDS( filelist )
249 copyfile = drv_dir'\' || WORD( filelist, i )
250 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
251 CALL LINEOUT globals.!log1, ' -' copyfile '(REQUIRED):' ok
252 END
253 DROP copyfile
254 DROP filelist
255 END
256 ELSE RETURN 0
257
258 /* If there are optional files defined as well, try to copy those also.
259 */
260 IF SysGetEA( driver, 'OPTIONALDRIVERFILES', 'reqfiles') == 0 THEN DO
261 PARSE VAR reqfiles 5 filelist
262 filelist = TRANSLATE( filelist, ' ', ',')
263 DO i = 1 TO WORDS( filelist )
264 copyfile = drv_dir'\' || WORD( filelist, i )
265 IF STREAM( copyfile, 'C', 'QUERY EXISTS') == '' THEN ITERATE
266 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
267 CALL LINEOUT globals.!log1, ' -' copyfile '(OPTIONAL):' ok
268 END
269 DROP copyfile
270 DROP filelist
271 END
272
273RETURN 1
274
275
276/*:VRX PrinterExistsInDRV
277*/
278/* Determine if the specified PrinterPak driver already contains support
279 * for the specified printer model.
280 */
281PrinterExistsInDRV: PROCEDURE EXPOSE globals.
282 PARSE UPPER ARG driver_name, printer_name
283 printer_name = TRANSLATE( printer_name, '_', '.')
284
285 printer_drv = globals.!os2dir'\DLL\'driver_name'\'driver_name'.DRV'
286 /* ?? TODO: install driver_name if not found (prompt first) ?? */
287
288 IF SysGetEA( printer_drv, '.EXPAND', 'exist_ea') <> 0 THEN RETURN 0
289 PARSE VAR exist_ea 1 _eatype 3 .
290 IF C2X( _eatype ) <> 'FDFF' THEN RETURN 0
291
292 PARSE VAR exist_ea 3 _ealen 5 exist_models
293 total_len = C2D( REVERSE( _ealen ))
294
295 /* The variable exist_models now contains a null-separated list of printer
296 * models supported by the driver (including those from previously-imported
297 * PPD files). Next we check each one against our requested printer name.
298 */
299 start = 1
300 found = 0
301 DO WHILE ( found == 0 ) & ( start < total_len )
302 _strend = POS('0'x, exist_models, start )
303 IF _strend == 0 THEN LEAVE
304 _model = TRANSLATE( SUBSTR( exist_models, start, _strend - start ))
305 IF _model == printer_name THEN
306 found = 1
307 ELSE
308 start = _strend + 1
309 END
310
311RETURN found
312
313
314/*:VRX CreateDriverList
315*/
316/* Generate a driver listfile from the .EXPAND EA
317 */
318CreateDriverList: PROCEDURE EXPOSE globals.
319 ARG driver, listfile
320
321 IF STREAM( listfile, 'C', 'QUERY EXISTS') <> '' THEN
322 CALL SysFileDelete listfile
323
324 drv_name = FILESPEC('NAME', driver )
325 IF SysGetEA( driver, '.EXPAND', 'eaval') == 0 THEN DO
326 PARSE VAR eaval 3 ealen 5 models
327 offs = 1
328 datalen = C2D( REVERSE( ealen ))
329 DO WHILE offs <= datalen
330 start = SUBSTR( models, offs )
331 inc = POS('00'x, start )
332 IF inc > 1 THEN DO
333 current_name = STRIP( SUBSTR( start, 1, inc-1 ))
334 CALL LINEOUT listfile, current_name':' current_name '('drv_name')'
335 END
336 offs = offs + inc
337 END
338 CALL LINEOUT listfile
339 CALL LINEOUT globals.!log1, 'Created driver list' listfile 'for' driver'.'
340 END
341 ELSE
342 CALL LINEOUT globals.!log1, 'No drivers found in' driver '(missing .EXPAND extended attribute?)'
343
344RETURN 1
345
346
347/*:VRX AddPort_CUPS
348*/
349/* Adds a new CUPS port. Returns 0 on full success, 1 if the port was created
350 * but could not be configured, and an OS/2 or PM error code otherwise.
351 */
352AddPort_CUPS: PROCEDURE EXPOSE globals.
353 PARSE ARG portname, hostname, queuename
354 CALL LINEOUT globals.!log1, 'Creating new port' portname
355 ADDRESS CMD '@cupsport' portname hostname queuename '>>' globals.!log2
356 IF rc == 1 THEN DO
357 CALL VRSetIni 'PM_'portname, 'INITIALIZATION', hostname'#'queuename||'00'x, 'SYSTEM', 'NoClose'
358 CALL VRSetIni 'PM_'portname, 'DESCRIPTION', hostname':'queuename||'00'x, 'SYSTEM'
359 END
360RETURN rc
361
362
363/*:VRX DeletePort
364*/
365/* Deletes a printer port (any type).
366 */
367DeletePort: PROCEDURE EXPOSE globals.
368 PARSE ARG portname
369 CALL SysIni 'SYSTEM', 'PM_'portname, 'DELETE:'
370 CALL SysIni 'SYSTEM', 'PM_SPOOLER_PORT', portname, 'DELETE:'
371RETURN 1
372
373
374/*:VRX GetNextPortName
375*/
376/* Get the next unique (non-existing) port name for the specified port driver.
377 */
378GetNextPortName: PROCEDURE
379 ARG portdrv
380
381 maxports = 64 /* should be smarter about this if possible */
382 exists = 1
383 x = 0
384 DO WHILE ( x < maxports ) & ( exists == 1 )
385 x = x + 1
386 portname = portdrv || x
387 nextport = SysIni('SYSTEM', 'PM_SPOOLER_PORT', portname )
388 IF LEFT( nextport, 6 ) == 'ERROR:' THEN exists = 0
389 END
390 IF exists == 1 THEN
391 portname = ''
392
393RETURN portname
394
395
396/*:VRX GetPortDrivers
397*/
398/* Get the list of currently-installed port drivers. NOTE: we exclude LPRPDRVR
399 * from this list, because it has to be managed via the TCP/IP configuration
400 * program.
401 */
402GetPortDrivers: PROCEDURE EXPOSE portdrivers.
403 ok = SysIni('SYSTEM', 'PM_PORT_DRIVER', 'ALL:', 'installed.')
404 IF LEFT( ok, 6 ) == 'ERROR:' THEN RETURN 0
405 count = 0
406 DO i = 1 TO installed.0
407 IF installed.i = 'LPRPDRVR' THEN ITERATE
408 fullpath = STRIP( SysIni('SYSTEM', 'PM_PORT_DRIVER', installed.i ), 'T', '00'x )
409 IF LEFT( fullpath, 6 ) == 'ERROR:' THEN fullpath = ''
410 fullpath = STREAM( fullpath , 'C', 'QUERY EXISTS')
411 count = count + 1
412 portdrivers.count = installed.i || ' ' || fullpath
413 END
414 portdrivers.0 = count
415RETURN portdrivers.0
416
417
418/*:VRX GetQueueName
419*/
420/* Generate a unique queue name from the specified printer name.
421 */
422GetQueueName: PROCEDURE
423 ARG queuename
424
425 DO UNTIL badchar = 0
426 badchar = VERIFY( queuename, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789 ')
427 IF badchar > 0 THEN
428 queuename = OVERLAY(' ', queuename, badchar, 1 )
429 END
430 queuename = LEFT( SPACE( queuename, 0 ), 8 )
431
432 tail = 0
433 PARSE VALUE VRGetIni('PM_SPOOLER', 'DIR', 'SYSTEM') WITH spldir ';' .
434 DO WHILE VRFileExists( spldir'\'queuename ) == 1
435 tail = tail + 1
436 queuename = STRIP( LEFT( queuename, 8 - LENGTH( tail ))) || tail
437 END
438
439RETURN queuename
440
441
442/*:VRX InstallPortDriver
443*/
444/* Installs a new port driver.
445 *
446 * Returns: 0 on success, 1 on error
447 */
448InstallPortDriver: PROCEDURE EXPOSE globals.
449 ARG new_pdr
450 filename = VRParseFileName( new_pdr, 'NE')
451 IF filename == '' THEN RETURN
452 installed_pdr = TRANSLATE( globals.!os2dir'\DLL\'filename )
453 IF installed_pdr <> new_pdr THEN DO
454 ok = VRCopyFile( new_pdr, installed_pdr )
455 IF ok == 0 THEN RETURN 1
456 /* Try to copy any optional files as well */
457 IF SysGetEA( new_pdr, 'OPTIONALDRIVERFILES', 'reqfiles') == 0 THEN DO
458 drv_dir = VRParseFilePath( new_pdr, 'DP')
459 PARSE VAR reqfiles 5 filelist
460 filelist = TRANSLATE( filelist, ' ', ',')
461 DO i = 1 TO WORDS( filelist )
462 copyfile = drv_dir'\' || WORD( filelist, i )
463 IF STREAM( copyfile, 'C', 'QUERY EXISTS') == '' THEN ITERATE
464 ok = VRCopyFile( copyfile, newdrvdir'\' || WORD( filelist, i ))
465 /*CALL LINEOUT globals.!log1, ' -' copyfile '(OPTIONAL):' ok*/
466 END
467 END
468 END
469
470 key = VRParseFileName( installed_pdr, 'N')
471 CALL VRSetIni 'PM_PORT_DRIVER', key, installed_pdr||'00'x, 'SYSTEM'
472RETURN 0
473
474
475/*:VRX InstallPrintDriver
476*/
477/* 'Installs' (that is to say, registers with the spooler) an OS printer
478 * device driver/model. Installs the corresponding printerpak driver if
479 * necessary.
480 *
481 * driver - The name of the printerpak driver (without path or extension)
482 * driverfull - The fully-qualified filename of the printerpak driver
483 * model - The printer make/model name used by the driver
484 *
485 * Returns: 0 on success, 1 on error
486 */
487InstallPrintDriver: PROCEDURE EXPOSE globals.
488 PARSE ARG driver, driverfull, model
489
490 ok = 0
491 targetdir = globals.!os2dir'\DLL\'driver
492 targetdrv = targetdir'\'driver'.DRV'
493 CALL LINEOUT globals.!log1, 'Installing' driver'.'model 'from' driverfull '(target' targetdrv')'
494
495 IF ( VRFileExists( targetdrv ) == 0 ) THEN DO
496 CALL VRMkDir targetdir
497 r = CopyPrinterPak( driverfull, targetdir )
498 IF r <> 1 THEN ok = 1
499 END
500 IF ok == 0 THEN DO
501 IF VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER') <> targetdrv THEN
502 CALL VRSetIni 'PM_DEVICE_DRIVERS', driver, targetdrv||'00'x, 'USER'
503 CALL VRSetIni 'PM_SPOOLER_DD', driver'.'model, driver'.DRV;;;'||'00'x, 'SYSTEM'
504 END
505RETURN ok
506
507/*:VRX DeletePrintDriver
508*/
509/* Removes (that is to say, de-registers with the spooler) a PM printer
510 * device driver/model.
511 *
512 * driver - The name of the printerpak driver (without path or extension)
513 * model - The printer make/model name used by the driver
514 *
515 * Returns: 0 on success, 1 on error
516 */
517DeletePrintDriver: PROCEDURE EXPOSE globals.
518 PARSE ARG driver, model
519
520 ok = VRDelIni('PM_SPOOLER_DD', driver'.'model, 'SYSTEM')
521RETURN ok
522
523/*:VRX CreatePrinterObject
524*/
525/* Create the specified printer using SysCreateObject (this should create the
526 * queue automatically).
527 *
528 * Returns: 0 on success or non-zero return code on error.
529 */
530CreatePrinterObject: PROCEDURE EXPOSE globals.
531 PARSE ARG driver, model, portname, queuename, printername
532
533 CALL LINEOUT globals.!log1, 'Creating new printer:' printername '('queuename')'
534 ok = RPUPrinterCreate( printername, queuename, portname, driver'.'model )
535RETURN ok
536
537/*:VRX GetNameFromPPD
538*/
539GetNameFromPPD: PROCEDURE
540 ARG ppd_file
541
542 IF STREAM( ppd_file, 'C', 'QUERY EXISTS') == '' THEN RETURN ''
543 nickname = ''
544 IF VRParseFilePath( ppd_file, 'E') == 'GZ' THEN DO
545 nq = RXQUEUE('CREATE')
546 oq = RXQUEUE('SET', nq )
547 ADDRESS CMD '@gzip -c -d' ppd_file '| RXQUEUE' nq
548 DO QUEUED()
549 PARSE PULL line
550 line = STRIP( line )
551 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
552 PARSE VAR line . ':' _nick '0D'x .
553 nickname = STRIP( _nick )
554 nickname = STRIP( nickname, 'B', '"')
555 LEAVE
556 END
557 END
558 CALL RXQUEUE 'SET', oq
559 CALL RXQUEUE 'DELETE', nq
560 END
561 ELSE DO
562 CALL LINEIN ppd_file, 1, 0
563 DO WHILE LINES( ppd_file ) <> 0
564 line = STRIP( LINEIN( ppd_file ))
565 IF LEFT( line, 15 ) == '*ShortNickName:' THEN DO
566 PARSE VAR line . ':' _nick '0D'x .
567 nickname = STRIP( _nick )
568 nickname = STRIP( nickname, 'B', '"')
569 LEAVE
570 END
571 END
572 CALL STREAM ppd_file, 'C', 'CLOSE'
573 END
574
575RETURN nickname
576
577/*:VRX CleanPPD
578*/
579/* Clean out lines from Gutenprint and Foomatic PPD files that are known to
580 * cause problems when importing with PIN. (Partially based on work by Paul
581 * Smedley and Peter Brown).
582 */
583CleanPPD: PROCEDURE
584 PARSE ARG in_ppd, logfile
585 IF logfile <> '' THEN
586 logfile = STREAM( logfile, 'C', 'QUERY EXISTS')
587
588 out_ppd = VRParseFilePath( in_ppd, 'DPN') || '.TMP'
589 IF STREAM( out_ppd, 'C', 'QUERY EXISTS') \= '' THEN
590 CALL SysFileDelete out_ppd
591
592 IF logfile <> '' THEN
593 CALL CHAROUT logfile, 'Doing cleanup on' in_ppd '...'
594
595 skip_next = 0
596 DO WHILE LINES( in_ppd ) \= 0
597 line = LINEIN( in_ppd )
598 SELECT
599 WHEN skip_next == 1 THEN DO
600 line = STRIP( TRANSLATE( line ))
601 IF line == '*END' THEN skip_next = 0
602 END
603 WHEN LEFT( line, 11 ) == '*StpDefault' THEN NOP
604 WHEN LEFT( line, 7 ) == '*StpStp' THEN NOP
605 WHEN LEFT( line, 18 ) == '*StpResolutionMap:' THEN NOP
606 WHEN LEFT( line, 14 ) == '*OPOptionHints' THEN NOP
607 WHEN LEFT( line, 4 ) == '*da.' THEN NOP
608 WHEN LEFT( line, 4 ) == '*de.' THEN NOP
609 WHEN LEFT( line, 4 ) == '*es.' THEN NOP
610 WHEN LEFT( line, 4 ) == '*fi.' THEN NOP
611 WHEN LEFT( line, 4 ) == '*fr.' THEN NOP
612 WHEN LEFT( line, 4 ) == '*it.' THEN NOP
613 WHEN LEFT( line, 4 ) == '*ja.' THEN NOP
614 WHEN LEFT( line, 4 ) == '*ko.' THEN NOP
615 WHEN LEFT( line, 4 ) == '*nb.' THEN NOP
616 WHEN LEFT( line, 4 ) == '*nl.' THEN NOP
617 WHEN LEFT( line, 4 ) == '*pt.' THEN NOP
618 WHEN LEFT( line, 4 ) == '*sv.' THEN NOP
619 WHEN LEFT( line, 7 ) == '*zh_CN.' THEN NOP
620 WHEN LEFT( line, 7 ) == '*zh_TW.' THEN NOP
621 WHEN LEFT( line, 9 ) == '*Foomatic' THEN DO
622 line = STRIP( line )
623 IF RIGHT( line, 2 ) == '&&' THEN skip_next = 1
624 END
625 OTHERWISE DO
626 CALL LINEOUT out_ppd, line
627 skip_next = 0
628 END
629 END
630 END
631 CALL STREAM in_ppd, 'C', 'CLOSE'
632 CALL STREAM out_ppd, 'C', 'CLOSE'
633
634 ok = VRCopyFile( out_ppd, in_ppd )
635 IF logfile <> '' THEN DO
636 IF ok == 1 THEN
637 CALL LINEOUT logfile, 'OK'
638 ELSE DO
639 CALL LINEOUT logfile, 'Failed!'
640 CALL LINEOUT logfile, ' ->' VRError()
641 END
642 CALL LINEOUT logfile, ''
643 END
644 CALL SysFileDelete out_ppd
645
646RETURN
647
648/*:VRX MatchPrinterModel
649*/
650/* Find a set of printers supported by the OS/2 driver which mostly closely
651 * match the given name.
652 */
653MatchPrinterModel: PROCEDURE EXPOSE globals. models.
654 PARSE UPPER ARG driver_name, printer_name
655 printer_name = TRANSLATE( printer_name, '_', '.')
656 printer_drv = globals.!os2dir'\DLL\'driver_name'\'driver_name'.DRV'
657 models.0 = 0
658
659 IF SysGetEA( printer_drv, '.EXPAND', 'exist_ea') <> 0 THEN RETURN 0
660 PARSE VAR exist_ea 1 _eatype 3 .
661 IF C2X( _eatype ) <> 'FDFF' THEN RETURN 0
662
663 PARSE VAR exist_ea 3 _ealen 5 exist_models
664 total_len = C2D( REVERSE( _ealen ))
665
666 /* The variable exist_models now contains a null-separated list of printer
667 * models supported by the driver (including those from previously-imported
668 * PPD files). Next we check each one against our requested printer name.
669 */
670 start = 1
671 count = 0
672 best = 0
673 DO WHILE start < total_len
674 _strend = POS('0'x, exist_models, start )
675 IF _strend == 0 THEN LEAVE
676 _model = TRANSLATE( SUBSTR( exist_models, start, _strend - start ))
677 _model = TRANSLATE( _model, ' ', '-')
678 _comp = COMPARE( _model, printer_name )
679 IF WORD( _model, 1 ) == WORD( printer_name, 1 ) THEN DO
680 count = count + 1
681 IF _comp == 0 THEN DO
682 _comp = 9999
683 best = count
684 END
685 ELSE IF ( best == 0 ) & ( _comp > LENGTH( printer_name )) THEN
686 best = count
687/*
688 models.count = RIGHT( _comp, 4, '0') SUBSTR( exist_models, start, _strend - start )
689*/
690 models.count = SUBSTR( exist_models, start, _strend - start )
691 END
692 start = _strend + 1
693 END
694 models.0 = count
695
696/*
697 CALL SysStemSort 'models.', 'D', 'I',,, 1, 4
698 DO i = 1 TO count
699 models.i = SUBWORD( models.i, 2 )
700 END
701*/
702RETURN best
703
704
705/*:VRX CheckWritablePath
706*/
707CheckWritablePath: PROCEDURE EXPOSE globals.
708 ARG path
709
710 /* Make sure path exists & is a directory */
711 IF \VRIsDir( path ) THEN RETURN 1
712
713 /* Make sure the drive is accessible */
714 di = SysDriveInfo( VRParseFilePath( path, 'DP'))
715 IF di == '' THEN RETURN 2
716
717 /* Make sure the drive has a supported filesystem */
718 fs = SysFileSystemType( prdrv )
719 IF WORDPOS( fs, 'HPFS JFS FAT FAT32') == 0 THEN RETURN 3
720
721RETURN 0
722
723
724/*:VRX QueryAvailableDrivers
725*/
726/* Determine which of our supported PrinterPak drivers are currently available.
727 */
728QueryAvailableDrivers: PROCEDURE EXPOSE globals. drv_list.
729 drv_list.0 = 0
730
731 test_drivers = 'ECUPS ECUPS-HP PSPRINT'
732 DO i = 1 TO WORDS( test_drivers )
733 driver = WORD( test_drivers, i )
734 ok = GetDriverSource( driver )
735 IF ok == '' THEN
736 ok = VRGetIni('PM_DEVICE_DRIVERS', driver, 'USER')
737 IF ok <> '' THEN
738 CALL SysStemInsert 'drv_list.', drv_list.0+1, driver
739 END
740
741RETURN drv_list.0
742
743
744/*:VRX UpdatePrDesc
745*/
746UpdatePrDesc: PROCEDURE EXPOSE globals.
747 ARG driver, fqn
748
749 IF globals.!prdesc == '' THEN RETURN 1
750
751 ok = RPUEnumModels( fqn, 'newdevs.')
752 IF ok == 0 THEN RETURN 2
753
754 _count = 0
755 CALL LINEIN globals.!prdesc, 1, 0
756 DO WHILE LINES( globals.!prdesc )
757 _next = LINEIN( globals.!prdesc )
758 PARSE UPPER VAR _next WITH . ':' . '('_prdrv')' .
759 IF _prdrv == driver THEN ITERATE
760 _count = _count + 1
761 prdefs.count = _next
762 END
763 CALL STREAM globals.!prdesc, 'C', 'CLOSE'
764
765 DO i = 1 TO devs.0
766 _count = _count + 1
767 prdefs._count = newdevs.i':' newdevs.i '('driver')'
768 END
769 prdefs.0 = count
770
771 CALL VRSortStem 'prdefs.'
772
773 _prdir = VRParseFileName( globals.!prdesc, 'DP')
774 CALL VRCopyFile globals.!prdesc, _prdir'\PRDESC.BAK'
775 CALL VRDeleteFile globals.!prdesc
776 DO i = 1 TO prdefs.0
777 CALL LINEOUT globals.!prdesc, prdefs.i
778 END
779 CALL LINEOUT globals.!prdesc
780
781RETURN 0
782
783
784/*:VRX NLSGetMessage
785*/
786/*
787 * Gets the message text associated with the given message number from the
788 * current language file.
789 */
790NLSGetMessage: PROCEDURE EXPOSE globals.
791 PARSE ARG msgnum, .
792 args = ARG()
793
794 msgfile = globals.!messages
795 IF msgnum == '' THEN RETURN ''
796
797 sub_parms = ''
798 DO i = 2 TO args
799 sub_parms = sub_parms', "'ARG( i )'"'
800 END
801
802 INTERPRET 'msgfromfile = SysGetMessage( msgnum, msgfile' sub_parms ')'
803
804 PARSE VAR msgfromfile message '0D'x .
805 IF SUBSTR( message, 1, 4 ) == 'SYS0' THEN message = ''
806
807RETURN message
808
809
810/*:VRX NLSSetText
811*/
812/*
813 * Sets the specified property of the specified control to the specified
814 * message text.
815 */
816NLSSetText: PROCEDURE EXPOSE globals.
817 PARSE ARG control, property, message, substitution
818 args = ARG()
819
820 success = 1
821 IF args < 4 THEN
822 text = NLSGetMessage( message )
823 ELSE DO
824 sub_parms = ''
825 DO i = 4 TO args
826 sub_parms = sub_parms '"'|| ARG( i ) ||'",'
827 END
828 sub_parms = STRIP( sub_parms, 'T', ',')
829 INTERPRET 'text = NLSGetMessage( message, 'sub_parms')'
830 END
831
832 IF text == '' THEN success = 0
833 ELSE CALL VRSet control, property, text
834
835RETURN success
836
837/*:VRX StringTokenize
838*/
839StringTokenize:
840 PARSE ARG string, separator, __stem
841 CALL __StringTokenize string, separator, __stem
842 DROP __stem
843RETURN
844
845/*:VRX __StringTokenize
846*/
847__StringTokenize: PROCEDURE EXPOSE (__stem)
848 PARSE ARG string, separator, tokens
849
850 /* Note: this differs slightly from my usual implementation in that
851 * each token is STRIPped of leading and trailing spaces.
852 */
853
854 IF ( string = '') THEN RETURN string
855 IF ( separator = '') THEN separator = ' '
856
857 i = 0
858 CALL VALUE tokens || '0', i
859 DO WHILE LENGTH( string ) > 0
860 x = 1
861 y = POS( separator, string, x )
862 IF y > 0 THEN DO
863 current = SUBSTR( string, 1, y-1 )
864 x = y + 1
865 i = i + 1
866 CALL VALUE tokens || 'i', STRIP( current )
867 END
868 ELSE DO
869 current = STRIP( string, 'B', separator )
870 i = i + 1
871 CALL VALUE tokens || 'i', STRIP( current )
872 x = LENGTH( string ) + 1
873 END
874 string = SUBSTR( string, x )
875 END
876 CALL VALUE tokens || '0', i
877
878RETURN
879
Note: See TracBrowser for help on using the repository browser.