XlBWFriends.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, September 29, 1992
Christian Jacobi, December 16, 1992 10:18 am PST
DIRECTORY
SF, Xl, XlBitmap;
This is a quite private internal interface. It may be changed outside of the release cycle.
Package which supports implementation of bitmap backed windows. For drawing, clients simply draw into a bitmap. Clients do not have to worry about locking or complex performance requirements of paint procedures to windows.
It is appropriate to make a private interface because I intend to have the essence of bitmap windows exported lower than the toolkit (usable by many toolkits). However, I don't want to miss the benefits of trusted usage (complexity and speed) from only within trusted widget implementors either.
Clients have know changes to the window themselves. Window changes may happen completely asynchronously with any drawing. The client can allocate a new bitmap for backing the viewer's content and request this package to take notice of the new bitmap.
Once a client hands over a bitmap to a bitmap window, the client must not change the structure of the bitmap anymore [size, bits per pixel, location of bitmap in memory...]. The client may however at all times change the bits without any synchronization. This package itself will never change neither bits nor structure of any bitmap handed to it.
XlBWFriends: CEDAR DEFINITIONS
~ BEGIN
empty: SF.Box ~ [min: SF.maxVec, max: SF.minVec];
ReportRec: TYPE = RECORD [proc: PROC [SF.Box, REF], data: REF];
bufferSize: INT ~ <<PRIVATE>> 64;
Index: TYPE = [0..bufferSize);
WRef: TYPE = REF WRec; --one per window
WRec: TYPE = RECORD [
--fields initialized by clients
c: Xl.Connection ¬ NIL,
bm: XlBitmap.Bitmap ¬ NIL,
report: LIST OF ReportRec ¬ NIL,
clip: SF.Box ¬ empty, --Coordinate system of bm, intersection of bm and window area
s: SRef ¬ NIL, --Do not change once StartWRef has been called
overheadCost: INT ¬ 7, --cost of overhead per request
--The following fields are to be considered private
ix, ox: PRIVATE Index ¬ 0,
-- ix=ox means empty;
-- buffer[ix] is field ready to be filled (if buffer not full)
-- buffer[ox] is field ready to be removed (if buffer not empty)
-- (ix+1) mod size = ox means full
costs: PRIVATE ARRAY Index OF INT ¬ ALL[0],
rects: PRIVATE ARRAY Index OF SF.Box ¬ ALL[[[0, 0], [0, 0]]],
sNo: PRIVATE Xl.SequenceNo ¬ 0,
emptyCount: PRIVATE CARD ¬ 0,
serverQueueCnt: PRIVATE INT ¬ 0,
serverQueueLimit: PRIVATE INT ¬ 256,
emptySleepersCnt: PRIVATE INT ¬ 0,
emptySleepers: PRIVATE CONDITION, --producers which wait until their requests are handled.
slowedProducersCnt: PRIVATE INT ¬ 0,
slowedProducers: PRIVATE CONDITION, --producers waiting for space in buffer. Times out because notification is delayed
extraRefForImpl: PRIVATE REF ¬ NIL,
--The following fields are useful for some favorite clients, but,
--not used by the implementation
d: Xl.Drawable ¬ [0],
offset: Xl.Point ¬ [0, 0], --position in d where origin of bm goes
base: LONG POINTER ¬ NIL,
gc: Xl.GContext ¬ NIL,
scanLineBytes: INT ¬ 0,
sharedD: Xl.Drawable ¬ Xl.nullDrawable,
extraRefForClient: REF ¬ NIL
];
SRef: TYPE = REF SRec; --one per shared
SRec: PRIVATE TYPE = MONITORED RECORD [
processExists: BOOL ¬ FALSE,
allHandles: LIST OF WRef ¬ NIL, -- a handle is included at most once
next: LIST OF WRef ¬ NIL,
changed: BOOL ¬ FALSE, --better don't go to sleep if something changed
consumerSleeps: BOOL ¬ FALSE,
sleepingConsumer: CONDITION
];
NewSRef: PROC [] RETURNS [SRef];
--New, and, initializes fields reasonably.
StartWRef: PROC [w: WRef];
--Trust caller that w will be stopped again: really uses resources while running.
--Trust caller that necessary fields are initialized (c, bm, clip).
--Be aware: fields are accessed asynchronously and must not be modified by caller any more.
--Do rather allocate a a new WRef instead of fooling around.
--If SRef field is NIL, it will be shared within service
StopWRef: PROC [w: WRef];
--Call this when window gets destroyed (or unmapped)
--Be aware: asynchronous access stops after some time only
IncludeRect: PROC [s: SRef, w: WRef, r: SF.Box, delayOk: BOOL ¬ FALSE];
--I apologize for requireing the SRef parameter, but, I need it for the locking.
--Precondition: r clipped; r not empty
CancelRects: PROC [s: SRef, w: WRef];
--Cancels refresh requests queued but not yet sent to X server.
WaitLocal: PROC [s: SRef, w: WRef] RETURNS [timedOut: BOOL];
--Wait for timout, or, until all requests are sent
END.