Copyright (C) 1994, Digital Equipment Corp. UNSAFE MODULE-- public procedures -- New and NewFromImage are implementation-specific and contained in PictureImpl.m3Picture EXPORTSPicture ,PictureRep ; IMPORT Batch, BatchRep, BatchUtil, Completion, Ctypes, PictureRep, PaintExt, PaintPrivate, Point, Rect, Thread, VBT, VBTRep, Word;
PROCEDURE-- types and methods --Paint ( v : VBT.Leaf; src : T; READONLY clip := Rect.Full; READONLY delta := Point.Origin; freeProc : FreeProc := NIL; freeParam: REFANY := NIL ) RAISES {Thread.Alerted} = CONST bsize = ADRSIZE(PaintExt.PictureRec); size = bsize DIV ADRSIZE(Word.T); VAR p: PaintExt.PicturePtr; completion := PictureRep.MakeCompletion(src).init( 1, freeProc, freeParam); BEGIN LOCK v DO IF v.remaining < bsize THEN IF v.st = NIL THEN RETURN END; VBTRep.NewBatch(v, size); END; DEC(v.remaining, bsize); WITH b = v.batch DO p := b.next; INC(b.next, bsize); p.ext.command := PaintPrivate.PaintCommand.ExtensionCom; p.ext.clip := clip; p.ext.szOfRec := size; p.ext.delta := delta; p.ext.subCommand := PaintExt.PictureCommand; p.picture := LOOPHOLE(src, ADDRESS); (* see the note PaintExt.i3 *) p.completion := LOOPHOLE(completion, ADDRESS); BatchUtil.SetPicture(b); END; VBTRep.ForceBatch(v); END; VBT.Sync(v, FALSE); IF freeProc = NIL THEN (* synchronous version *) TRY completion.waitUntilFree(); FINALLY IF NOT completion.isFree() THEN completion.dec(); END; Completion.Dispose(completion); END; END; END Paint; PROCEDUREDestroy (picture: T) = BEGIN picture.destroy(); END Destroy; PROCEDUREAttachData (picture: T; dataPtr: Ctypes.char_star; shmInfo: SharedMemInfo := NIL) RAISES {TrestleFail} = BEGIN picture.attachData(dataPtr, shmInfo); END AttachData; PROCEDUREDetachData (picture: T) RAISES {TrestleFail} = BEGIN picture.detachData(); END DetachData; PROCEDUREImage (picture: T): ImageStar = BEGIN RETURN picture.image; END Image;
REVEAL T = Public BRANDED OBJECT OVERRIDES init := TInit; initFromImage := TInitFromImage; attachData := TAttachData; detachData := TDetachData; destroy := DestroyCrash; END; PROCEDURE-- utilities --TInit ( t : T; <* UNUSED*> st : VBT.ScreenType; <* UNUSED*> width, height: CARDINAL ): T = BEGIN RETURN t; END TInit; PROCEDURETInitFromImage ( t : T; <* UNUSED*> st : VBT.ScreenType; image: ImageStar; <* UNUSED*> sharedMemory := FALSE): T = BEGIN t.allocByCaller := TRUE; t.image := image; RETURN t; END TInitFromImage; PROCEDURETAttachData ( picture: T; dataPtr: Ctypes.char_star; <* UNUSED*> shmInfo: SharedMemInfo := NIL) = BEGIN picture.image.data := dataPtr; END TAttachData; PROCEDURETDetachData (picture: T) = BEGIN picture.image.data := NIL; END TDetachData; EXCEPTION Fatal; PROCEDUREDestroyCrash (<* UNUSED *> picture: T) = <* FATAL Fatal *> BEGIN RAISE Fatal; END DestroyCrash;
TYPE LockElt = UNTRACED REF Word.T; PROCEDUREFreeze (picture: T): Lock = VAR res: Lock; BEGIN res.a := LOOPHOLE(ADR(picture), LockElt); IF picture # NIL THEN res.b := LOOPHOLE(picture.image, LockElt); IF picture.image # NIL THEN res.c := LOOPHOLE(picture.image.data, LockElt) END END; RETURN res; END Freeze; PROCEDUREThaw (<*UNUSED*> l: Lock) = BEGIN END Thaw; TYPE WalkProc = PROCEDURE (completion: Completion.T); PROCEDUREDecrementBatch (ba: Batch.T) = PROCEDURE Dec (comp: Completion.T) = BEGIN comp.dec(); END Dec; BEGIN WalkBatch(ba, Dec); END DecrementBatch; PROCEDUREIncrementBatch (ba: Batch.T) = PROCEDURE Inc (comp: Completion.T) = BEGIN comp.inc(); END Inc; BEGIN WalkBatch(ba, Inc); END IncrementBatch; PROCEDUREWalkBatch (ba: Batch.T; proc: WalkProc) = VAR cptr: PaintPrivate.CommandPtr := BatchUtil.Succ(ba, NIL); BEGIN WHILE cptr # NIL DO IF cptr.command = PaintPrivate.PaintCommand.ExtensionCom THEN WITH op = LOOPHOLE(cptr, PaintExt.PicturePtr) DO IF op.ext.subCommand = PaintExt.PictureCommand THEN (* see PaintExt.i3 for LOOPHOLE *) proc(LOOPHOLE(op.completion, Completion.T)); END; END; END; cptr := BatchUtil.Succ(ba, cptr); END; END WalkBatch; BEGIN END Picture.