Copyright (C) 1994, Digital Equipment Corp.
VBTRep.def, code Sun Aug 11 12:18:43 1985 by Greg Nelson
<*PRAGMA LL*>The
VBTRep interface defines the representation of VBTs, and provides
operations that are useful for implementing low-level or esoteric
split classes.
INTERFACETo save space in aVBTRep ; IMPORT Batch, Cursor, PropertyV, Rect, Region, ScreenType, ScrnPaintOp, ScrnCursor, ScrnPixmap, ScrnFont, VBT, VBTClass, Word, PaintPrivate, Axis, Palette, PaintOp, Font, Pixmap; CONST EmptyCage = VBT.EmptyCage; TYPE MiscRef = REF MiscRec; MiscRec = RECORD cage := EmptyCage; badRgn := Region.Empty; rpseqno: Word.T; oldDomain := Rect.Empty; link: MiscRef := NIL END;
VBT, the cage, badRgn, rpseqno, and
oldDomain fields are only stored if at least one of them has an
``unusual'' value. This is achieved by including a MiscRef in the
VBT object. If the MiscRef is NIL, then the badRgn and oldDomain
are empty, the rpseqno is irrelevant, and the cage is determined
from the cagetype field as follows: if the cagetype is
VBT.CageType.Rectangle, then the cage rectangle is assumed to be
Rect.Empty; otherwise the rectangle is irrelevant.
The rpseqno field is the {\it repainting sequence number}. It is
incremented whenever the badRgn is expanded and recorded before
activating a repaint method. Thus when the repaint method returns,
the current value can be compared with the recorded value to
determine whether the current badRgn is the one that the repaint
method responded to, or whether a new bad region arrived while the
client was responding to the old one.
TYPE
Prop =
{EscapePending, Reshaping, RepaintPending, OnQ,
Covered, Combiner, ShortCircuit, CageCovered,
Marked, ExcessBegins, HasNewShape, BlockNewShape,
EscapeCovered};
Props = SET OF Prop;
CONST
AllProps = Props{FIRST(Prop)..LAST(Prop)};
NoProps = Props{};
Here is the meaning of the properties:
EscapePending: Set when a thread of control is forked to deliver a
cage escape to gone. Set to FALSE when any position is delivered.
Reshaping: set when the VBT has a non-empty old domain.
RepaintPending: Set when a thread of control exists that will deliver
the bad region.
OnQ: Set when the VBT is on the Metermaid's to-be-serviced queue.
Covered: Ordinarily painting into an empty batch will put the
VBT on the Metermaid's queue and set onQ. If the covered
bit is set, this will not happen. For example, PutPosition sets
covered before passing the position to child, and clears it and
forces the batch before it returns. Only set during event delivery,
so any action that could be deferred until after event delivery can
check covered and clean up on method exit.
Combiner: Set to indicate that this VBT is a good place to pile up
small paint batches, even if it is not covered. Trestle sets this bit
in one VBT near the root of a client address space to avoid shipping
many small batches across RPC.
ShortCircuit: Set on a VBT when painting on the VBT can be
implemented by clipping to the VBT's domain and painting on its
parent.
Marked: set by VBT.Mark.
CageCovered: VBTClass.PutPosition sets this bit on a VBT before
calling its position method; after calling the position method,
the procedure relays the child's cage to the parent and clears
the bit. VBTClass.SetCage notices the bit and omits relaying the
cage to the parent.
ExcessBegins: Set when excessBegins > 0.
HasNewShape is set when VBT.NewShape is called, and cleared by
a call to VBTClass.HasNewShape or VBTClass.GetShape.
If BlockNewShape is set, VBT.NewShape calls will not be relayed
to the parent of the VBT.
REVEAL VBT.Prefix =
VBTClass.Prefix BRANDED OBJECT
<* LL >= {SELF} *>
cursor := Cursor.DontCare;
cageType: (*BITS 16 FOR*) VBTClass.VBTCageType
:= VBTClass.VBTCageType.Gone;
props: (*BITS 16 FOR*) Props := NoProps;
batch: Batch.T := NIL;
remaining: INTEGER := 0;
propset: PropertyV.Set := NIL;
miscRef: MiscRef := NIL;
OVERRIDES
getcursor := GetcursorDefault;
axisOrder := AxisOrderDefault;
END;
The batch field contains the batch of uncompleted painting commands
for the VBT, and remaining contains the number of free addressable
units remaining in the batch. In particular, if remaining # 0, the
batch field is not NIL. The miscRef field is always NIL
if the parent is NIL.
REVEAL VBT.ScreenType <: STPub;
TYPE STPub =
ScreenType.Public OBJECT
ops: REF ARRAY OF ScrnPaintOp.T;
cursors: REF ARRAY OF ScrnCursor.T;
pixmaps: REF ARRAY OF ScrnPixmap.T;
fonts: REF ARRAY OF ScrnFont.T
METHODS
opApply(cl: Palette.OpClosure; op: PaintOp.T): ScrnPaintOp.T;
cursorApply(cl: Palette.CursorClosure; cs: Cursor.T): ScrnCursor.T;
pixmapApply(cl: Palette.PixmapClosure; pm: Pixmap.T): ScrnPixmap.T;
fontApply(cl: Palette.FontClosure; ft: Font.T): ScrnFont.T
END;
The tables st.ops, st.fonts, st.cursors, and st.pixmaps are
collectively called the screentype's {\it palette}. They are used
to translate between screen-independent resources and
screen-dependent resources. For example, recall that Pixmap.Gray
is a record containing the integer field Pixmap.Gray.pm. The
screen-dependent equivalent of Pixmap.Gray on the screentype st
is simply st.pixmaps[Pixmap.Gray.pm]. When creating the palette,
the above apply methods are called for all resources; if cl is NIL, the
resource is built-in. The default values for these return the result of
invoking the closure or the built-in method; your procedure must not
return NIL when invoked on a built-in.
TYPE OffscreenType = VBT.ScreenType OBJECT st: VBT.ScreenType END;An
OffscreenType s, is a screen type that is derived from the screen
type s.st. An OffscreenType will be replaced by its associated
screentype in calls to Trestle.InstallOffscreen. The st field
is read-only after creation.
PROCEDURE CheckMisc(v: VBT.T); <* LL >= {v} *>
Setv.misc := NILifv'sbadRgnandoldDomainare empty and its cage type is notRect.
PROCEDURE CreateMisc(v: VBT.T); <* LL >= {v} *>
Ifv.misc = NIL, then create amiscforvwith emptybadRgnandoldDomain, and with appropriate cage. Otherwise, do nothing.
PROCEDURE DestroyMisc(v: VBT.T);
<* LL >= {v, v.parent} *>
Setv's misc toNIL, clearingReshapingfromv.props.
PROCEDURE NewBatch(v: VBT.T; len: INTEGER := -1); <* LL.sup = v *>
Forcev's batch if it is non-nil and allocate a new batch for it of size at leastlen, or of sizeVBTTuning.BatchSizeiflen=-1.
PROCEDURE ForceBatch(v: VBT.T); <* LL.sup = v *>
Force v's batch if it is non-nil, and leave it nil. PROCEDURE CancelBatch(v: VBT.T); <* LL.sup = v *>
Freev's batch and set it toNIL.
PROCEDURE Enqueue(v: VBT.T); <* LL.sup = v *>
Placevon the list ofVBTsscheduled to be serviced by the MeterMaid.
PROCEDURE GetcursorDefault(v: VBT.Prefix): ScrnCursor.T;
Return the result of resolvingcursor(v)usingv's screentype.
PROCEDURE AxisOrderDefault(v: VBT.Prefix): Axis.T;
Return Axis.T.Hor. PROCEDURE ExpandBadRect(w: VBT.T; READONLY clp: Rect.T; ba: Batch.T); <* LL.sup = w *>
Expandw's bad region forba.
In
ExpandBadRect, the rectangle clp is the original clipping
rectangle for ba, before intersection with w.domain. The
expansion is caused by (a) using out-of-domain bits as source (b)
painting into the old domain (c) scrolling an existing bad rectangle.
PROCEDURE ExtendBatch(v: VBT.T; VAR ba: Batch.T);
Extendv's batch to include the painting operations inba, and freeba. It is assumed thatvhas a non-empty batch which has room for the extension.
PROCEDURE MaxRepeat(v: VBT.T): CARDINAL; <* LL.sup = v *>
Return the number of RepeatRec's that can fit in v's current batch.
PROCEDURE PaintRepeat(v: VBT.T; READONLY clip: ARRAY OF Rect.T); <* LL.sup = v *>
Add aRepeatRectov's batch for each rectangle inclip.
PaintRepeat is a checked run-time error if there isn't enough space
in v's batch. Calling PaintRepeat does not call
Enqueue(v).
PROCEDURE PaintSingle(v: VBT.T; READONLY clip: Rect.T; com: PaintPrivate.CommandPtr); <* LL.sup = v *>
Add the paint operation referenced bycomtov's batch, but use the clipping rectangleclipinstead of the one incom.
PaintSingle forces v's batch if necessary and allocates a new
one. It does not call Enqueue(v). The command com must not be a
scroll command.
PROCEDURE Scroll(v: VBT.T; READONLY clip: Rect.T; com: PaintPrivate.ScrollPtr); <* LL.sup = v *>
LikePaintSingle, butcommust be a scroll command.
PROCEDURE Mark(v: VBT.T); <* LL >= {v} *>
Identical to VBT.Mark except for the locking level. PROCEDURE Redisplay(); <* LL.sup = VBT.mu *>
Redisplay and unmark all marked windows whose screentype is non-NIL. That is,
Redisplay is equivalent to this loop:
LOOP
WITH m = an array containing all marked windows DO
IF NUMBER(m) = 0 THEN EXIT END;
Sort m in order of non-decreasing depth;
FOR i := 0 TO LAST(m) DO
IF IsMarked(m[i]) AND m[i].st # NIL THEN
Unmark(m[i]);
m[i].redisplay()
END
END
END
END
The depth of a window is the number of parent pointers that must
be followed to reach NIL. Sorting by depth guarantees that
ancestors will be redisplayed before their descendants. The reason
is that redisplaying an ancestor window often reshapes its
descendants, and if a descendant is going to be reshaped it would
be wasteful to redisplay it in its old position.
Ordinarily when a window is marked, a thread is forked that will
call Redisplay. This is wasteful if Redisplay will be called
soon anyway. Therefore, if you know that Redisplay will be called
soon, you can call CoverRedisplay, which increments a ``coverage
counter''. If the coverage counter is non-zero, marking a VBT
does not fork a thread. Of course by calling CoverRedisplay you
acquire the obligation to ensure that Redisplay will be called
soon. Calling UncoverRedisplay decrements the counter and calls
Redisplay if the result is zero.
PROCEDURE CoverRedisplay(); <* LL.sup = VBT.mu *>
Increment the redisplay coverage counter.
PROCEDURE UncoverRedisplay(); <* LL.sup = VBT.mu *>
Decrement the redisplay coverage counter and call Redisplay if
the result is zero. END VBTRep.