DIRECTORY Atom, CedarProcess, IO, KeyTypes, NetworkStream, RemoteEventTime, RemoteImagerDataTypes, TerminalReceiver, TIPKeyboards, UserInputGetActions; TerminalReceiverImpl: CEDAR PROGRAM IMPORTS Atom, CedarProcess, IO, NetworkStream, RemoteEventTime, TIPKeyboards EXPORTS TerminalReceiver = BEGIN OPEN RET:RemoteEventTime, RIDT:RemoteImagerDataTypes, TerminalReceiver; keysym0: KeyTypes.KeySym ~ [0]; Decode: PUBLIC PROC [producer, indexSrc: IO.STREAM, et1: EventTime, version: NAT, Consumer: PROC [ActionBody], Repaint: PROC, TakeTimeReply: PROC [org, mid: EventTime, descToo: BOOL, desc: EventDesc], TakeCutBuffer: PROC [buffer: ATOM, key: CARD, data: ROPE], adjustTime: BOOL] = { DecodeProtected[producer, indexSrc, et1, version, Consumer, Repaint, TakeTimeReply, TakeCutBuffer, adjustTime ! IO.Error => <> CONTINUE; IO.EndOfStream => <> CONTINUE; NetworkStream.Timeout => RESUME]; RETURN}; DecodeProtected: PROC [producer, indexSrc: IO.STREAM, et1: EventTime, version: NAT, Consumer: PROC [ActionBody], Repaint: PROC, TakeTimeReply: PROC [org, mid: EventTime, descToo: BOOL, desc: EventDesc], TakeCutBuffer: PROC [buffer: ATOM, key: CARD, data: ROPE], adjustTime: BOOL] = { localStart: EventTime ~ RET.ReadEventTime[]; idx0: INT ~ IF indexSrc#NIL THEN indexSrc.GetIndex[] ELSE FIRST[INT]; GetChar: PROC RETURNS [CHAR] = INLINE {RETURN [producer.GetChar[]]}; GetByte: PROC RETURNS [BYTE] = INLINE {RETURN [GetChar[].ORD]}; GetEventTime: PROC RETURNS [EventTime] = { hi: CARD = GetCard[]; lo: CARDINAL = GetCardinal[]; RETURN [[hi: hi, lo: lo]]}; GetMousePosition: PROC RETURNS [MousePosition] = { mouseX: INTEGER = GetInteger[]; color: BOOL ¬ FALSE; mouseY: INTEGER ¬ GetInteger[]; IF mouseY < 0 THEN {color ¬ TRUE; mouseY ¬ mouseY + 32768}; RETURN [[mouseX, color, mouseY-16383]]}; GetCard: PROC RETURNS [CARD] = { hi: CARDINAL = GetCardinal[]; lo: CARDINAL = GetCardinal[]; RETURN [hi*65536 + lo]}; GetCardinal: PROC RETURNS [CARDINAL] = { hi: BYTE = GetByte[]; lo: BYTE = GetByte[]; RETURN [CARDINAL[hi]*256 + lo]}; GetInteger: PROC RETURNS [INTEGER] = { c: CARDINAL ~ GetCardinal[]; IF c <= INT16.LAST THEN RETURN [c]; RETURN [INT[c]-10000H]}; GetTimeAction: PROC RETURNS [et: EventTime] = { peekB: BYTE ~ producer.PeekChar[].ORD; IF peekB=RIDT.ActionKind.eventTime.ORD THEN { b2: BYTE ~ GetByte[]; dt: CARDINAL ~ GetByte[]; IF peekB#b2 OR dt#0 THEN ERROR; et ¬ GetEventTime[]; RETURN} ELSE RETURN [localStart]}; GetRope: PROC RETURNS [ROPE] ~ { len: NAT ~ GetCard[]; RETURN producer.GetRope[len, TRUE]}; nt: EventTime = [0, 0]; remoteStart: EventTime ~ GetTimeAction[]; deltaTime: EventTime ¬ nt; posns: ARRAY {mouse, pen} OF RECORD [known, color: BOOL, x, y: INT] ¬ ALL[[FALSE, FALSE, 0, 0]]; LogSize: NAT = 32; log: ARRAY [0..LogSize) OF RECORD [key: BYTE, idx: INT] ¬ ALL[[0, 0]]; logPtr: [0..LogSize) ¬ 0; ts: INT; IF adjustTime THEN TRUSTED { curOffset ¬ deltaTime ¬ RET.Sub[localStart, remoteStart]; } ELSE curOffset ¬ [0, 0]; deltaTime ¬ deltaTime.Sub[et1].Add[RET.SmallConsCC[0, 1]]; ts ¬ remoteStart.Add[deltaTime].ToSmall[]; Consumer[[$EventTime, [MAX[ts, 0]], 0]]; DO idx: INT ~ IF indexSrc#NIL THEN indexSrc.GetIndex[] ELSE FIRST[INT]; key: BYTE ~ GetByte[]; CedarProcess.CheckAbort[]; log[logPtr] ¬ [key, idx]; logPtr ¬ (logPtr.SUCC) MOD LogSize; SELECT key FROM <= RIDT.ActionKind.LAST.ORD => {kind: RIDT.ActionKind ~ VAL[key]; dt: INT ~ GetByte[]; ots: CARD ~ MAX[ts, 0]; rts: CARD; ts ¬ ts + dt; rts ¬ MAX[ts, 0]; SELECT kind FROM deltaEventTime => {ts ¬ ts + GetCardinal[]; rts ¬ MAX[ts, 0]; Consumer[[$TimeIsPassing, [rts], rts-ots]]}; keyDown, keyUp => {k: BYTE ~ GetByte[]; kc: KeyTypes.KeyCode ~ VAL[k]; Consumer[[$Key, [rts], rts-ots, NIL, NIL, NIL, kind=keyDown, kc, TIPKeyboards.KeySymsFromKeyCode[kc].keySym1]]}; keyStillDown, allUp => NULL; eventTime => TRUSTED {et: EventTime ¬ GetEventTime[]; ts ¬ MAX[et.Add[deltaTime].ToSmall[], ts]; rts ¬ MAX[ts, 0]; Consumer[[$EventTime, [rts], rts-ots]]}; deltaMouse => {b: BYTE = GetByte[]; hi: NAT = b/16; lo: NAT = b - hi*16; posns[mouse].x ¬ posns[mouse].x + hi - 8; posns[mouse].y ¬ posns[mouse].y + lo - 8; Consumer[[$IntegerPosition, [rts], rts-ots, NIL, NIL, NIL, FALSE, keycode0, keysym0, posns[mouse].x, posns[mouse].y, posns[mouse].x, posns[mouse].y, ColorToDisplay[posns[mouse].color]]]}; mousePosition => { [[mouseX: posns[mouse].x, mouseY: posns[mouse].y, color: posns[mouse].color]] ¬ GetMousePosition[]; posns[mouse].known ¬ TRUE; Consumer[[$IntegerPosition, [rts], rts-ots, NIL, NIL, NIL, FALSE, keycode0, keysym0, posns[mouse].x, posns[mouse].y, posns[mouse].x, posns[mouse].y, ColorToDisplay[posns[mouse].color]]]}; penPosition => [] ¬ GetMousePosition[]; timedOut => Consumer[[$TimeIsPassing, [rts], rts-ots]]; ENDCASE => ERROR; }; 16 => Repaint[]; 17 => {org, mid: EventTime; descToo: BOOL ~ version >= 13; desc: EventDesc; [org, mid, desc] ¬ GetTimeReply[producer, descToo]; TakeTimeReply[org, mid, descToo, desc]}; 18 => { bufferR: ROPE ~ GetRope[]; buffer: ATOM ~ Atom.MakeAtom[bufferR]; bkey: CARD ~ GetCard[]; data: ROPE ~ GetRope[]; TakeCutBuffer[buffer, bkey, data]}; ENDCASE => ERROR; ENDLOOP; }; curOffset: EventTime; ColorToDisplay: PROC [color: BOOL] RETURNS [display: ATOM] ~ { IF color THEN RETURN [$Color] ELSE RETURN [$Main]}; GetTimeReply: PUBLIC PROC [producer: IO.STREAM, descToo: BOOL] RETURNS [org, mid: EventTime, desc: EventDesc] ~ { GetEventTime: PROC RETURNS [EventTime] = { hi: CARD = GetCard[]; lo: CARDINAL = GetCardinal[]; RETURN [[hi: hi, lo: lo]]}; GetCard: PROC RETURNS [CARD] = { hi: CARDINAL = GetCardinal[]; lo: CARDINAL = GetCardinal[]; RETURN [hi*65536 + lo]}; GetCardinal: PROC RETURNS [CARDINAL] = { hi: BYTE = GetByte[]; lo: BYTE = GetByte[]; RETURN [CARDINAL[hi]*256 + lo]}; GetByte: PROC RETURNS [BYTE] = INLINE {RETURN [producer.GetChar[].ORD]}; dcopy: EventDesc ¬ [mousePosition: [0, FALSE, 0], action: [contents: timedOut[]]]; TRUSTED { org ¬ GetEventTime[]; mid ¬ GetEventTime[]; IF descToo THEN { n: INT ~ producer.UnsafeGetBlock[[base: LOOPHOLE[@dcopy], count: BYTES[EventDesc]]]; IF n = BYTES[EventDesc] THEN NULL ELSE IF producer.EndOf[] THEN ERROR IO.EndOfStream[producer] ELSE ERROR}; }; desc ¬ dcopy; RETURN}; END. žTerminalReceiverImpl.mesa Copyright Σ 1990, 1992 by Xerox Corporation. All rights reserved. Last tweaked by Mike Spreitzer on July 6, 1992 8:56 am PDT ΚΈ–(cedarcode) style•NewlineDelimiter ˜codešœ™Kšœ Οeœ7™BK™:—K˜Kš Οk œœžœœ œœœœœœœ˜—K˜šΟnœžœž˜#Kšžœœžœœœœ ˜LKšžœ˜K˜—K˜Kšžœžœžœžœ)˜MK˜K˜K˜šŸœžœž˜šœžœžœžœ˜=KšŸœžœ˜KšŸœžœ˜KšŸ œžœ žœ˜JKš Ÿ œžœ žœžœžœ˜:Kšœ žœ˜—˜oKšžœ>žœ˜IKšžœ.žœ˜9Kšœžœ˜!—Kšžœ˜—K˜šŸœž˜šœžœžœžœ˜=KšŸœžœ˜KšŸœžœ˜KšŸ œžœ žœ˜JKš Ÿ œžœ žœžœžœ˜:Kšœ žœ˜—Kšœžœ˜,Kšœžœžœ žœžœžœžœžœ˜EKš Ÿœžœžœžœžœžœ˜DKšŸœžœžœžœžœžœ žœ˜?šŸ œžœžœ˜*Kšœžœ ˜Kšœžœ˜Kšžœ˜—šŸœžœžœ˜2Kšœžœ˜Kšœžœžœ˜Kšœžœ˜Kšžœ žœ žœ˜;Kšžœ"˜(—šŸœžœžœžœ˜ Kšœžœ˜Kšœžœ˜Kšžœ˜—šŸ œžœžœžœ˜(Kšœžœ ˜Kšœžœ ˜Kšžœžœ˜ —šŸ œžœžœžœ˜&Kšœžœ˜Kš žœžœžœžœžœ˜#Kšžœžœ ˜—šŸ œžœžœ˜/Kšœžœžœ˜&šžœžœžœžœ˜-Kšœžœ ˜Kšœžœ ˜Kšžœ žœžœžœ˜K˜Kšžœ˜—Kšžœžœ˜—šŸœžœžœžœ˜ Kšœžœ ˜Kšžœžœ˜$—K˜K˜)K˜š œžœžœžœžœžœ˜CKšœžœžœžœ ˜—KšŸœžœ˜Kš œžœžœžœžœžœžœ ˜FK˜Kšœžœ˜šžœ žœžœ˜Kšœžœ˜9K˜—Kšžœ˜Kšœ#žœ˜:K˜*Kšœžœ˜(šž˜Kšœžœžœ žœžœžœžœžœ˜DKšœžœ ˜K˜K˜Kšœžœžœ ˜#Kšžœž˜š œžœ žœžœ žœžœ˜AKšœžœ ˜Kšœžœžœ˜Kšœžœ˜ K˜ Kšœžœ˜šžœž˜˜+Kšœžœ˜Kšœ,˜,—šœžœ ˜'Kšœžœ˜Kšœ žœžœžœC˜p—Kšœžœ˜šœ žœ!˜5Kšœžœ"˜*Kšœžœ˜Kšœ(˜(—šœžœ ˜#Kšœžœ˜Kšœžœ ˜K˜)K˜)Kš œ,žœžœžœžœ{˜»—šœ˜K˜cKšœžœ˜Kš œ,žœžœžœžœ{˜»—K˜'Kšœ7˜7Kšžœžœ˜—K˜—K˜˜Kšœ žœ˜K˜K˜3K˜(—˜Kšœ žœ ˜Kšœžœ˜&Kšœžœ ˜Kšœžœ ˜K˜#—Kšžœžœ˜Kšžœ˜—K˜Kšœ˜—K˜š Ÿœžœ žœžœ žœ˜>Kš žœžœžœ žœžœ ˜3—K˜šŸ œžœžœ žœžœ žœžœ+˜qšŸ œžœžœ˜*Kšœžœ ˜Kšœžœ˜Kšžœ˜—šŸœžœžœžœ˜ Kšœžœ˜Kšœžœ˜Kšžœ˜—šŸ œžœžœžœ˜(Kšœžœ ˜Kšœžœ ˜Kšžœžœ˜ —KšŸœžœžœžœžœžœžœ˜HKšœ'žœ&˜Ršžœ˜ K˜K˜šžœ žœ˜Kšœžœ"žœžœ˜TKšžœžœ žœž˜!Kš žœžœžœžœžœ˜