; ; File: PrintDriver.a ; ; Contains: generic printer shell ; ; We get called only if the driver has not yet been attached, so we must attach ; it. This involves getting the correct DRVR from the resource file pointed ; to by STR -8192 in the system file, and replacing ourselves with it. This ; will convince future calls to the print driver to go direct, until the driver ; gets purged, in which case we will get called again, and we simply go get the ; real driver again. ; ; Written by: Burt Sloane ; ; Copyright: © 1984-1990 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; <8> 8/14/90 dba move the TopMapHndl to the LoadDriver call ; <2> 8/7/90 NB Only calls PrLoadDriver if the GetResource('DRVR', -8192) fails. ; Most of the time (always?) it will succeed, but in certain ; background/foreground cases, we may have to force a reload. ; This speeds up text printing by huge piles. ; <1> 8/7/90 csd Rebuilding the Printing project ; <6> 4/21/90 dba Set CurMap to TopMapHndl before calling PrLoadDriver, stealing ; code from the old print driver. This fixes some obvious problems ; with background printing, but the entire MultiFinder ÒGetPrNameÓ ; mechanism is no longer appropriate with aliases to printers ; (instead of driver names); this must be fixed. Also note that ; using CurMap directly and bypassing CurResFile and UseResFile is ; naughty. ; <5> 4/6/90 NB Replaced with the MultiFinder .Print. Also added a call to ; PrLoadDriver. This replaces all the driver load hacks from before. ; <4> 3/6/90 DDG Made GetDrvrEntry restore the ResLoad low memory global. (It ; used to save it, but not restore it) ; <3> 1/4/90 dba get rid of an unneeded branch that caused a warning ; <2> 12/28/89 dba change from PROC to MAIN to get dead code stripping; get rid of ; resource map munging because RsrcMapEntry is now in every ROM ; <1.3> 11/17/89 dba got rid of checks for 64K ROMs ; <1.2> 8/28/89 SES removed references to nFiles ; <1.1> 6/20/89 CCH changed ForRam equates to "NOT ForRom" ; <1.0> 11/16/88 CCH added to EASE ; 4/25/88 JNP If GetString(-8192) fails, return resErr. ; 12/30/86 JTC Repair A386 above to use rsrc bit twiddling trap only on new ; machines. ; 12/19/86 LBH Set and return correct error after GetResource error occurs. ; Also puts printer resource file refnum in PrintVars area of low ; memory. ; 12/19/86 LBH Changed OpenRFPerm back to OpenResFile since this code is now ; permanently back in RAM. ; 11/9/86 JTC No code change, just an elaboration of C169/24Oct86 above. This ; stub driver has the momentous job of determining the true print ; driver, loading it, sneaking it into the RSRC map (on top of ; this stubÕs own entry), and transferring control to it. ItÕs the ; sneakiness weÕre concerned with here. When the true driver is ; loaded and detached, the RSRC mgr clears the RSRC bit the master ; ptr, as is to be expected. Alas, when the handle is stuffed into ; the map, that bit should be set to 1 so that ; consistency-checking code sniffing around the heaps and maps ; will not find anything amiss. There should be no REAL problem ; here, since the drivers are not modified in RAM and thus donÕt ; require any special purge service by the ResPurgeProc. ; 10/31/86 LAK Changed OpenResFile call to OpenRFPerm to avoid conflict with ; 'Q' INIT patch to former. ; 10/24/86 JTC/ALR Incorporated change made to system version of this ; file setting resource bit of driver handle after detaching ; it and stuffing it back on top of this very code. ; 10/9/86 bbm Modified to mpw aincludes. ; 9/23/86 JTC Change two BSETs to _HLocks, with subtle reg effects. ; 9/12/85 LAK Set the dRAMBased bit in the appropriate byte. ; 8/28/85 BBM added .include for tlasm-newequ.text. ; 8/26/85 Leo ROM-ized the driver, incorporating Larry's changes from his ; version: if for ROM, then set dNeedsLock bit, set dRAMBased bit ; when splicing in printer driver, and don't do the ; ReleaseResource on ourselves. Also incorporated use of ; RsrcMapEntry trap for ROM version. Changed code to be included ; from a superset file that has all the includes and the ; definition of the conditional assembly constants forROM and ; forRAM in it. ; 8/14/85 Leo Auugh! Hang bug in MacPaint was caused because there's a routine ; in some PrLink, somewhere, called PrNoPurge that does a ; GetResource('DRVR',2). How obnoxious! In order to work around ; this bug, we're writing the handle to DRVR -8192 into the ; resource map over the handle to DRVR 2. ; 7/31/85 LEO Added GetDefDrive and GoSetVol from Donion's Scrapbook ; 7/15/85 LEO Added version info corresponding to Cary's memo Eliminated ; copying of code into tempRect. Eliminated master pointer/back ; pointer swap. Eliminated closing of resource file (speedup, ; hopefully). ; 2/1/85 BAS fixed a bug in the error case introduced 16-Jan. also handled ; not getting the resource better ; 1/16/85 BAS let openres do the volume hacking for me ; 10/29/84 BAS took out the global flag, made it always close the resFile ; 9/12/84 BAS made STR -8192 not need to be in the system file for Bud ; 9/7/84 BAS Put in suggestions/bugs found by LAK & SC & RS { whew! } ; ; To Do: ; LOAD 'StandardEqu.d' INCLUDE 'PrPrivate.a' ; format of a resource map entry (we should use ResourceMgrPriv.a instead) RID EQU 0 RNameO EQU RID+2 RAttr EQU RNameO+2 RLocn EQU RAttr RHndl EQU RLocn+4 RESize EQU RHndl+4 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ; ; PrintDriver.a - .Print Patch for Juggler ; ; Copyright Apple Computer, Inc. 1986-1990 ; All rights reserved. ; ; Written by Phil Goldman ; ; This is the patch for the .Print driver in the System File ; ; PseudoCode: ; ; short ; DoOpen(paramBlock, DCEHandle) ; { ; DoDriver(OFFSET_OPEN, paramBlock, DCEHandle); ; } ; ; short ; DoPrime(paramBlock, DCEHandle, paramBlock, DCEHandle) ; { ; return DoDriver(OFFSET_PRIME, paramBlock, DCEHandle); ; } ; ; short ; DoControl(paramBlock, DCEHandle) ; { ; return DoDriver(OFFSET_CONTROL, paramBlock, DCEHandle); ; } ; ; short ; DoStatus(paramBlock, DCEHandle) ; { ; return DoDriver(OFFSET_STATUS, paramBlock, DCEHandle); ; } ; ; short ; DoClose(paramBlock, DCEHandle) ; { ; return DoDriver(OFFSET_CLOSE, paramBlock, DCEHandle); ; } ; ; ; DoDriver(offset, paramBlock, DCEHandle) ; long offset ; IOPBPtr paramBlock; ; Handle DCEHandle; ; { ; StringPtr localStrPtr, globalStrPtr; ; short refNum, oldvref; ; Handle drvrHandle; ; char enablePrTypeChanges; ; ; enablePrTypeChanges = TWGetPrTypeStrings(&localStrPtr, &globalStrPtr); ; ; if (RelString(localStrPtr, globalStrPtr) != 0) ; { ; if (enablePrTypeChanges != PRTYPE_CHANGESTATUS_DISABLED || offset == OFFSET_CLOSE) ; globalStrPtr = localStrPtr /* Ignore global or do the _Close on the old local */ ; else ; { ; (void)DoClose(paramBlock, DCEHandle); ; CloseResFile(PRINTVARS.refNum); /* Ignore the error -- might already be closed by high level or glue */ ; TWSetPrResRefNums(globalStrPtr, nil); ; if (offset != OFFSET_OPEN) ; (void)DoOpen(paramBlock, DCEHandle); ; } ; } ; ; PRINTVARS.refNum = OpenRFPerm(globalStrPtr, BOOTVOL, curPerm); ; if (ResErr != noErr) ; return ResErr; ; if (drvrHandle = Get1Resource('STR ', -8192) == nil || ResError != noErr) ; return ResError; ; HLock(drvrHandle); ; retval = (drvrHandle[drvrHandle[offset]])(paramBlock, DCEHandle); ; if (((*drvrHandle)->drvrFlags & dNeedsLock) == 0) ; HUnlock(drvrHandle); ; return retval; ; } ; ; ; Open Questions: ; (3) Should the real driver be passed a fake DCE ptr, or can it share with this one? ; (4) What happens if this driver gets purged? (Theoretically, it should not matter since it's always locked) ; (5) Should we still unlock the driver at the end if the trap has the IMMED bit set? ; (6) Where is question (1)? ; ; ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- STRING ASIS BLANKS ON ; NOTE: Make sure to change these if dispatch numbers ever change! _KernelDispatch OPWORD $A88F TWGETPRTYPESTRINGSID EQU 39 TWSETPRTYPESTRINGSID EQU 40 PRTYPE_CHANGESTATUS_SAME EQU (-1) PRTYPE_CHANGESTATUS_DISABLED EQU (0) PRTYPE_CHANGESTATUS_ENABLED EQU (1) PrintShopRefNum EQU 'cg' macro _PrLoadDriver move.l #$D8000000, -(SP) dc.w $A8FD endm ; ; PrShell PROC EXPORT ; OrnEntry ReadWriteCtlStatus_Flags EQU (1< move.l (A0),A0 ; deref <6> move.w 20(A0),-(sp) ; get the top map refNum *** equate? <6> _UseResFile ; use the top map for finding the driver alias <6> _PrLoadDriver ; function result is in D0 tst.w D0 ; test the error bnz.s ErrorZ ; exit on error subq #4,SP ;space for handle move.l #'DRVR',-(sp) ;type move.w #-8192,-(sp) ;ID _Get1Resource ;get the actual driver move.l (sp)+,D0 ;get the handle beq.s ForceErr ;(LBH)no handle, fail move.l D0,A3 tst.l (a3) ; data loaded? beq.s ForceErr ;(LBH)no data, fail ResetStack move.w (SP)+,D1 ;get back the call number move.w (SP)+,curMap ;restore the map ; Here we lock the driver, cuz code oughta be locked while it's executing. movea.l A3,A0 ; _HLock ; lock driver down movea.l (A0),A2 ; ptr to driver move.w 0(A2,D1.w),D1 ;get the offset for the correct call add.w d1,a2 ;get the address of the correct call ; Restore the necessary registers and execute the appropriate routine from ; the "real" print driver. movem.l (SP),A0-A1 ; Restore needed regs move.w PrintVars+$E,-(sp) ; save refnum for later move.l a3,-(sp) ; save a3 (routine can trash all registers) jsr (a2) ; go do it move.l (sp)+,a3 ; restore a3 (routine can trash all registers) move.l (a3),a2 ; get ptr to driver btst #dNeedLock, drvrFlags(a2) ; should it stay locked? bne.s NoUnlockNeeded ; if so, branch UnlockNeeded move.w CurMap,a2 ; save cur res file _UseResFile tst.w resErr ; error on _UseResFile (res file got closed in jsr (a2) call)? bne.s ResFileGone ; if is, don't unlock non-existent driver move.w a2,CurMap ; restore cur res file move.l a3,a0 _HUnlock ; otherwise, unlock it bra.s PDrDone NoUnlockNeeded addq.w #2,sp ; get rid of refnum ResFileGone PDrDone movem.l (sp)+,A0-A3 ; Restore all used regs bra.s CompletelyDone ; go to IODone or ret addr ; ; (LBH) Force resource manager error since something failed. ; ForceErr move.w resErr,d0 ; get expected error bne.s ErrorZ ; return with it move.w #resNotFound,d0 ; otherwise force an error ; Got here if the _GetResource or GetDrvrEntry failed, ; so clean up and go home. ; ErrorZ move.w D0,PrintVars ;save error code ; move.w (SP)+,D1 ;get back the call number move.w (SP)+,curMap ;restore the map movem.l (SP)+,A0-A3 ; CompletelyDone btst #9,ioTrap(A0) ;were we called Immed? bne.s @1 ;yes move.l jioDone,-(SP) ;no, go to ioDone @1 rts ;go away END