DIRECTORY Graphics USING [Context, DrawBox, GetBounds, Mark, Restore, Save, SetColor, white], PEDisplay USING [DrawSegment, DrawSegmentAndVertices], PERefresh, PETrajectoryOps USING [ForAllSegments, ForAllTrajectories, SegmentProc, TrajectoryProc], PETypes USING [Segment, Trajectory, TrajectoryList, TrajectoryNode], PEViewer USING [DrawInViewer, DrawProc], Process USING [Detach, priorityBackground, SetPriority], ViewerClasses USING [Viewer]; PERefreshImpl: CEDAR MONITOR IMPORTS Graphics, PEDisplay, PETrajectoryOps, PEViewer, Process EXPORTS PERefresh = BEGIN OPEN PEDisplay, PERefresh, PETrajectoryOps, PETypes, PEViewer; RefreshProcessData: TYPE = REF RefreshProcessDataRec; RefreshProcessDataRec: TYPE = RECORD [ pathViewer: ViewerClasses.Viewer _ NIL, clientRedrawProc: DrawProc _ NIL, trajectoryList: TrajectoryList _ NIL, activeTrajectory: TrajectoryNode _ NIL, state: RefreshProcessState _ alive, refreshCondition: CONDITION, eraseFirst: BOOLEAN _ FALSE, screenNeedsRefreshing: BOOLEAN _ FALSE ]; RefreshProcessState: TYPE = {alive, dying}; CreateRefreshProcess: PUBLIC PROCEDURE [pathViewer: ViewerClasses.Viewer, clientRedrawProc: DrawProc _ NIL] RETURNS [data: RefreshData] = { refreshProcessData: RefreshProcessData _ NEW[RefreshProcessDataRec _ [pathViewer: pathViewer, clientRedrawProc: clientRedrawProc]]; TRUSTED {Process.Detach[FORK RefreshProcess[refreshProcessData]]}; RETURN [refreshProcessData]; }; DestroyRefreshProcess: PUBLIC ENTRY PROCEDURE [data: RefreshData] = { refreshProcessData: RefreshProcessData _ NARROW[data]; refreshProcessData.state _ dying; NOTIFY refreshProcessData.refreshCondition; }; EnableSegmentRefresh: PUBLIC ENTRY PROCEDURE [segment: Segment] = { IF segment # NIL THEN segment.refresh _ TRUE; }; DisableSegmentRefresh: PUBLIC ENTRY PROCEDURE [segment: Segment] = { IF segment # NIL THEN segment.refresh _ FALSE; }; EnableTrajectoryRefresh: PUBLIC ENTRY PROCEDURE [trajectory: Trajectory] = { IF trajectory # NIL THEN trajectory.refresh _ TRUE; }; DisableTrajectoryRefresh: PUBLIC ENTRY PROCEDURE [trajectory: Trajectory] = { IF trajectory # NIL THEN trajectory.refresh _ FALSE; }; NewRefreshData: PUBLIC ENTRY PROCEDURE [data: RefreshData, trajectoryList: TrajectoryList, activeTrajectory: TrajectoryNode] = { refreshProcessData: RefreshProcessData _ NARROW[data]; refreshProcessData.trajectoryList _ trajectoryList; refreshProcessData.activeTrajectory _ activeTrajectory; }; RequestRefresh: PUBLIC ENTRY PROCEDURE [data: RefreshData, erase: BOOLEAN _ FALSE] = { refreshProcessData: RefreshProcessData _ NARROW[data]; refreshProcessData.eraseFirst _ erase; refreshProcessData.screenNeedsRefreshing _ TRUE; NOTIFY refreshProcessData.refreshCondition; }; RefreshProcess: PRIVATE PROCEDURE [myData: RefreshProcessData] = { DoErase: DrawProc = { mark: Graphics.Mark _ Graphics.Save[context]; Graphics.SetColor[context, Graphics.white]; Graphics.DrawBox[context, Graphics.GetBounds[context]]; Graphics.Restore[context, mark]; }; DoRefreshTrajectory: TrajectoryProc = { DoRefreshSegment: SegmentProc = { RefreshSegment[data: myData, segment: s.first, trajectory: t]; }; ForAllSegments[t.first.segments, DoRefreshSegment]; }; TRUSTED {Process.SetPriority[Process.priorityBackground]}; WHILE myData.state = alive DO WaitForWork[myData]; IF myData.state # alive THEN EXIT; IF myData.eraseFirst THEN DrawInViewer[myData.pathViewer, DoErase]; IF myData.clientRedrawProc # NIL THEN DrawInViewer[myData.pathViewer, myData.clientRedrawProc]; ForAllTrajectories[myData.trajectoryList, DoRefreshTrajectory]; ENDLOOP; }; WaitForWork: PRIVATE ENTRY PROCEDURE [data: RefreshProcessData] = { WHILE ~data.screenNeedsRefreshing AND data.state = alive DO WAIT data.refreshCondition; ENDLOOP; data.screenNeedsRefreshing _ FALSE; }; RefreshSegment: PRIVATE ENTRY PROCEDURE [data: RefreshProcessData, segment: Segment, trajectory: TrajectoryNode] = { IF segment # NIL AND segment.refresh THEN { IF trajectory = data.activeTrajectory THEN DrawSegmentAndVertices[pathViewer: data.pathViewer, segment: segment, background: FALSE] ELSE DrawSegment[pathViewer: data.pathViewer, segment: segment, background: TRUE]; }; }; END. JPERefreshImpl.mesa Written by Darlene Plebon on August 31, 1983 11:23 am Refresh process routines. This process redraws the entire image at background priority whenever it is notified that an operation has been performed which may have damaged the displayed image. Active segments and vertices are NOT redrawn. Vertices are only drawn for the active trajectory. This routine creates the refresh process. This routine causes the refresh process to kill itself. This routine allows the specified segment to be refreshed on refresh requests. This routine prevents the specified segment from being refreshed. This routine allows the specified trajectory to be refreshed on refresh requests. This routine prevents the specified trajectory from being refreshed. This procedure provides information about the image to be refreshed. In particular, it provides a list of trajectories to be refreshed and which trajectory is active (i.e. the trajectory whose vertices are to be refreshed). This routine should be called whenever this information changes. This routine requests that the image be refreshed. It may optionally request that the screen be erased first. The routine is the refresh process which redraws the entire image at background priority. This routine waits for a refresh request from the path editor. This routine refreshes a segment. Ê[˜Jšœ™Jšœ5™5J˜J™£J˜šÏk ˜ Jšœ œE˜SJšœ œ'˜6Jšœ ˜ JšœœC˜XJšœœ7˜DJšœ œ˜(Jšœœ+˜8Jšœœ ˜J˜—šœœ˜Jšœ7˜?Jšœ ˜—J˜Jšœœ:˜DJ˜Jšœœœ˜5šœœœ˜&Jšœ#œ˜'Jšœœ˜!Jšœ!œ˜%Jšœ#œ˜'J˜#Jšœ œ˜Jšœ œœ˜Jšœœ˜&J˜—J˜šœœ˜+J˜—š Ïnœœ œAœœ˜‹J™)Jšœ)œW˜ƒJšœœ&˜BJšœ˜J˜—J˜šžœ œ œ˜EJ™7Jšœ)œ˜6Jšœ!˜!Jšœ%˜+J˜—J˜šžœ œ œ˜CJ™NJšœ œœœ˜-J˜—J˜šžœ œ œ˜DJ™AJšœ œœœ˜.J˜—J˜šžœ œ œ˜LJ™QJšœœœœ˜3J˜—J˜šžœ œ œ˜MJ™DJšœœœœ˜4J˜—J˜šžœ œ œZ˜€J™¢Jšœ)œ˜6Jšœ3˜3Jšœ7˜7J˜—J˜šžœ œ œœ˜VJ™nJšœ)œ˜6Jšœ&˜&Jšœ+œ˜0Jšœ%˜+J˜—J˜šžœœ!˜BJ™Yšžœ˜J˜-J˜+J˜7J˜ J˜—šžœ˜'šžœ˜!Jšœ>˜>J˜—Jšœ3˜3J˜—Jšœ3˜:šœ˜J˜Jšœœœ˜"Jšœœ*˜CJšœœœ:˜_Jšœ?˜?Jšœ˜—J˜—J˜šž œ œ œ˜CJ™>šœœ˜;Jšœ˜Jšœ˜—Jšœœ˜#J˜—J˜šžœœœ œM˜tJ™!šœ œœœ˜+Jšœ$œSœ˜ƒJšœHœ˜RJ˜—J˜—J˜Jš˜—…—Fë