<> <> <> 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.