DIRECTORY BitBlt USING [AlignedBBTable, BITBLT, BBptr, BBTableSpace], Buttons, Cursors USING [SetCursor], CGScreen USING [Bits], Environment USING [BitAddress], InputFocus, Mopcodes, Process, TIPUser, UserTerminal, ViewerLocks USING [LockViewerTree, ReleaseViewerTree], ViewerClasses, ViewerSpecs USING [screenH, screenW]; Magnifier: PROGRAM IMPORTS BitBlt, Buttons, Cursors, CGScreen, InputFocus, Process, TIPUser, UserTerminal, ViewerLocks SHARES ViewerLocks = BEGIN OPEN Mopcodes; pMask: REF; -- pointer to mask bits (0 => opaque, 1 => transparent) pImage: REF; -- pointer to image bits (0 => white, 1 => black) pSaved: REF; -- pointer to screen bits (0 => white, 1 => black) pRaster: CARDINAL; -- words per line pWidth: CARDINAL; -- width in bits pHeight: CARDINAL; -- height in lines pX, pY: INTEGER; -- last position lock: BOOL; -- viewer paints locked out magnify: BOOL _ FALSE; magX, magY, magW, magH: CARDINAL; AllocateBitmap: PROC [nWords: CARDINAL] RETURNS [REF] = INLINE BEGIN Words: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF CARDINAL]; RETURN[NEW[Words[nWords]]]; END; MagnifyRegion: PROC [leftX, topY, widthInWords, height: CARDINAL] = BEGIN magnify _ TRUE; magX _ leftX; magY _ topY; magW _ widthInWords; magH _ height; END; NewPicture: PROC [mask: REF, image: REF, raster, width, height, screenX, screenY: CARDINAL, lockPainting: BOOL _ TRUE] = BEGIN pMask _ mask; pImage _ image; pSaved _ AllocateBitmap[raster*height]; pRaster _ raster; pWidth _ width; pHeight _ height; pX _ MIN[screenX, ViewerSpecs.screenW-width]; screenY _ ViewerSpecs.screenH-screenY; -- invert conversion pY _ MIN[screenY, ViewerSpecs.screenH-height]; lock _ lockPainting; ComputeScreenPoint[]; sfsp.dst _ [LOOPHOLE[pSaved],,0]; sfsp.dstBpl _ pRaster*16; sfsp.width _ pWidth; sfsp.height _ pHeight; itsp.srcDesc.srcBpl _ pRaster*16; itsp.width _ pWidth; itsp.height _ pHeight; Cursors.SetCursor[blank]; IF lock THEN ViewerLocks.LockViewerTree[]; BLTImageToScreen[]; END; MovePicture: PROC [screenX, screenY: CARDINAL] = BEGIN BLTSavedToScreen[]; pX _ MIN[screenX, ViewerSpecs.screenW-pWidth]; screenY _ ViewerSpecs.screenH-screenY; -- invert conversion pY _ MIN[screenY, ViewerSpecs.screenH-pHeight]; ComputeScreenPoint[]; BLTImageToScreen[]; END; TakeDownPicture: PROC = BEGIN BLTSavedToScreen[]; IF lock THEN ViewerLocks.ReleaseViewerTree[]; Cursors.SetCursor[textPointer]; pMask _ pImage _ pSaved _ NIL; magnify _ FALSE; END; ComputeScreenPoint: PROC = INLINE BEGIN screenPoint.word _ screen + (LONG[pY]*(ViewerSpecs.screenW/16)) + (LONG[pX]/16); screenPoint.bit _ pX MOD 16; END; screen: LONG POINTER _ CGScreen.Bits[].base; screenPoint: Environment.BitAddress; sfsTable, itsTable: BitBlt.BBTableSpace; sfsp: BitBlt.BBptr _ BitBlt.AlignedBBTable[@sfsTable]; itsp: BitBlt.BBptr _ BitBlt.AlignedBBTable[@itsTable]; Pair: TYPE = ARRAY [0..1] OF CARDINAL; PairPtr: TYPE = LONG POINTER TO Pair; Get8: PROC [ptr: LONG POINTER, start: CARDINAL] RETURNS [word: CARDINAL] = INLINE { dist: INTEGER = CardinalAnd[start,15]; pp: PairPtr = LOOPHOLE[ptr, PairPtr] + start / 16; RETURN [ CardinalOr[ CardinalShiftLeft[pp[0], dist], CardinalShiftLeft[pp[1], dist-16]] / 256]; }; Put16: PROC [ptr: LONG POINTER, start: CARDINAL, word: CARDINAL] = INLINE { dist: INTEGER = CardinalAnd[start,15]; pp: PairPtr = LOOPHOLE[ptr, PairPtr] + start / 16; pp[0] _ CardinalOr[ CardinalShiftRight[word, dist], CardinalAnd[pp[0], CardinalShiftLeft[177777B, 16-dist]]]; pp[1] _ CardinalOr[ CardinalShiftLeft[word, 16-dist], CardinalAnd[pp[1], CardinalShiftRight[177777B, dist]]]; }; CardinalShiftLeft: PROC [word: CARDINAL, dist: INTEGER] RETURNS [CARDINAL] = MACHINE CODE { Mopcodes.zSHIFT; }; CardinalShiftRight: PROC [word: CARDINAL, dist: INTEGER] RETURNS [CARDINAL] = MACHINE CODE { Mopcodes.zNEG; Mopcodes.zSHIFT; }; CardinalOr: PROC [word1,word2: CARDINAL] RETURNS [CARDINAL] = MACHINE CODE { Mopcodes.zOR; }; CardinalAnd: PROC [word1,word2: CARDINAL] RETURNS [CARDINAL] = MACHINE CODE { Mopcodes.zAND; }; BLTImageToScreen: PROC = BEGIN itsp.dst _ sfsp.src _ screenPoint; BitBlt.BITBLT[sfsp]; -- save screen IF magnify THEN BEGIN screenAdd: LONG CARDINAL _ (magY+magH/4)*pRaster + magX/16; imageAdd: LONG CARDINAL _ magY*pRaster + magX/16; fetchOffset: CARDINAL = magX+magW*16/4; screen: LONG POINTER = LOOPHOLE[pSaved]; image: LONG POINTER = LOOPHOLE[pImage]; THROUGH [0..magH/2) DO FOR i: CARDINAL IN [0..magW) DO word: CARDINAL = twoPower[Get8[screen+screenAdd, fetchOffset+(8*i)]]; xOff: CARDINAL = magX+(16*i); Put16[image+imageAdd, xOff, word]; Put16[image+imageAdd+pRaster, xOff, word]; ENDLOOP; screenAdd _ screenAdd + pRaster; imageAdd _ imageAdd + (2*pRaster); ENDLOOP; END; IF pMask#NIL THEN BEGIN itsp.src _ [LOOPHOLE[pMask],,0]; itsp.flags.dstFunc _ and; BitBlt.BITBLT[itsp]; itsp.flags.dstFunc _ or; END; itsp.src _ [LOOPHOLE[pImage],,0]; BitBlt.BITBLT[itsp]; itsp.flags.dstFunc _ null; END; BLTSavedToScreen: PROC = INLINE BEGIN itsp.dst _ screenPoint; itsp.src _ [LOOPHOLE[pSaved],,0]; BitBlt.BITBLT[itsp]; END; twoPower: ARRAY [0..256) OF CARDINAL; BuildTwoPower: PROC = BEGIN scan: INTEGER; p: POINTER TO PACKED ARRAY [0..8) OF BOOL _ LOOPHOLE[@scan]; p2: POINTER TO PACKED ARRAY [0..16) OF BOOL _ LOOPHOLE[@twoPower]; FOR i: INTEGER IN [0..256) DO scan _ i; FOR j: INTEGER IN [0..8) DO p2[j*2] _ p[j]; p2[j*2+1] _ p[j]; ENDLOOP; p2 _ p2+1; ENDLOOP; END; magnifier: REF ARRAY [0..256) OF UNSPECIFIED _ LOOPHOLE[AllocateBitmap[256]]; magnifier2: REF ARRAY [0..512) OF UNSPECIFIED _ LOOPHOLE[AllocateBitmap[512]]; Start: Buttons.ButtonProc = TRUSTED BEGIN InputFocus.SetInputFocus[]; InputFocus.CaptureButtons[Notify, myTIPTable]; IF mouseButton#red THEN BEGIN MagnifyRegion[1, 1, 7, 62]; NewPicture[NIL, magnifier2, 8, 114, 64, 300, 300]; END ELSE BEGIN MagnifyRegion[1, 1, 3, 62]; NewPicture[NIL, magnifier, 4, 50, 64, 300, 300]; END; Process.Detach[FORK DoIt[]]; END; Notify: ViewerClasses.NotifyProc = TRUSTED {}; -- NOP myTIPTable: TIPUser.TIPTable _ TIPUser.InstantiateNewTIPTable["Magnifier.tip"]; -- Known NOP fudge: CARDINAL _ 150; -- fudge for retrace synch DoIt: PROCEDURE = BEGIN mouseBitsRec: TYPE = MACHINE DEPENDENT RECORD [ -- mouse buttons are inverted fill: [0..8192), red: BOOL, blue: BOOL, yellow: BOOL]; mouseP: LONG POINTER TO mouseBitsRec = LOOPHOLE[UserTerminal.keyboard]; mouse: UserTerminal.Coordinate; Process.SetPriority[3]; UNTIL ~mouseP.red DO wait: CARDINAL; UserTerminal.WaitForScanLine[ SELECT wait _ pY+fudge FROM >808 => 0, ENDCASE => wait]; IF UserTerminal.cursor^ # mouse THEN BEGIN mouse _ UserTerminal.cursor^; MovePicture[mouse.x, 808-mouse.y]; END; ENDLOOP; TakeDownPicture[]; InputFocus.ReleaseButtons[]; END; sfsp.flags.disjoint _ TRUE; sfsp.flags.disjointItems _ TRUE; sfsp.srcDesc.srcBpl _ ViewerSpecs.screenW; itsp.flags.disjoint _ TRUE; itsp.flags.disjointItems _ TRUE; itsp.dstBpl _ ViewerSpecs.screenW; BuildTwoPower[]; magnifier[0] _ magnifier[1] _ magnifier[2] _ 177777B; magnifier[252] _ magnifier[253] _ magnifier[254] _ 177777B; magnifier[3] _ 140000B; magnifier[255] _ 140000B; FOR i: INTEGER IN [0..248/4) DO magnifier[i*4+4] _ 100000B; magnifier[i*4+7] _ 040000B; ENDLOOP; FOR i: INTEGER IN [0..6] DO magnifier2[i] _ 177777B; magnifier2[i+504] _ 177777B; ENDLOOP; magnifier2[7] _ magnifier2[511] _ 140000B; FOR i: INTEGER IN [0..62) DO magnifier2[i*8+8] _ 100000B; magnifier2[i*8+15] _ 040000B; ENDLOOP; [] _ Buttons.Create[[name: "Magnifier"], Start]; END. ŒMagnifier.mesa; Written by S. McGregor Last Edited by: McGregor, July 18, 1983 9:17 am Last Edited by: Beach, October 4, 1983 3:38 pm Κ )– "Mesa" style˜Jšœ Οc™&Jšœ/™/J™.šΟk ˜ Jšœžœžœ˜;Jšœ˜Jšœžœ ˜Jšœ žœ˜Jšœ žœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ Jšœ žœ%˜6Jšœ˜Jšœ žœ˜%—šœ ž˜Jšžœ\˜cJšžœž œž˜)—J˜Jšœžœ8˜DJšœžœ2˜?Jšœžœ2˜?Jšœ žœ˜$Jšœžœ˜"Jšœ ž œ˜%Jšœžœ˜!Jšœžœ˜'Jšœ žœžœ˜Jšœžœ˜!J˜š Οnœžœ žœžœžœžœž˜DJšœžœžœžœžœžœžœžœ˜=Jšžœžœ˜Jšžœ˜J˜—šŸ œžœ%žœž˜IJšœ žœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšžœ˜—J˜šŸ œžœžœ žœ+ž œžœžœž˜~Jšœ ˜ Jšœ˜Jšœ'˜'Jšœ˜Jšœ˜Jšœ˜Jšœžœ%˜-Jšœ'˜;Jšœžœ&˜.Jšœ˜J˜Jšœ˜Jšœ žœ ˜!Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜J˜Jšœ˜Jšžœžœ˜*J˜Jšœ˜Jšžœ˜J˜—šŸ œžœžœž˜6Jšœ˜Jšœžœ&˜.Jšœ'˜;Jšœžœ'˜/Jšœ˜Jšœ˜Jšžœ˜J˜—šŸœžœž˜Jšœ˜Jšžœžœ!˜-Jšœ˜Jšœžœ˜Jšœ žœ˜Jšžœ˜J˜—šŸœžœžœž˜'Jšœžœ"žœ ˜PJšœžœ˜Jšžœ˜—J˜Jšœžœžœ˜,Jšœžœ ˜$J˜Jšœ(˜(J˜Jšœ6˜6Jšœ6˜6J˜Jš œžœžœžœžœ˜&Jš œ žœžœžœžœ˜%J˜šŸœžœžœžœ žœžœžœžœ˜SJšœžœ˜&Jšœžœ˜2šžœ˜šœ ˜ Jšœ˜Jšœ"˜"—Jšœ˜—J˜J˜—šŸœžœžœžœ žœžœžœ˜KJšœžœ˜&Jšœžœ˜2šœ˜Jšœ˜Jšœ9˜9—šœ˜Jšœ!˜!Jšœ7˜7—J˜J˜—šŸœž˜Jš œžœžœžœžœžœžœ˜CJšœ˜J˜J˜—šŸœž˜Jš œžœžœžœžœžœžœ˜CJšœ˜Jšœ˜J˜J˜—šŸ œžœžœžœžœžœžœ˜LJšœ ˜ J˜J˜—šŸ œžœžœžœžœžœžœ˜MJšœ˜J˜J˜J˜—šŸœžœž˜Jšœ"˜"Jšœžœ˜#šžœ žœž˜Jšœ žœžœ#˜;Jšœ žœžœ˜1Jšœ žœ˜'Jšœžœžœžœ ˜(Jšœžœžœžœ ˜'šžœ ž˜šžœžœžœ ž˜Jšœžœ7˜EJšœžœ˜Jšœ"˜"Jšœ*˜*Jšžœ˜—Jšœ ˜ Jšœ"˜"Jšžœ˜—Jšžœ˜—šžœžœžœž˜Jšœ žœ ˜ Jšœ˜Jšœžœ˜Jšœ˜Jšžœ˜—Jšœ žœ ˜!Jšœžœ˜Jšœ˜Jšžœ˜J˜—šŸœžœžœž˜%Jšœ˜Jšœ žœ ˜!Jšœžœ˜Jšžœ˜J˜—Jšœ žœ žœžœ˜%J˜šŸ œžœž˜Jšœžœ˜Jšœžœžœžœžœžœžœžœ˜