<> <> <> <> <<>> DIRECTORY SF, Xl, XlBitmap; <> <<>> <> <<>> <> <<>> <> <<>> <> 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 ~ <> 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.