// // BCPL keyboard handler // last edited August 25, 1980 1:47 PM // // Copyright Xerox Corporation 1979, 1980 get "kbdDefs.d" get "sysdefs.d" // for OsBUF structure get "altodefs.d" // for mouse and cursor locations external [ // procedures defined KBDHandler kbdState kbdGets kbdPuts kbdReset kbdEmpty ] external [ // statics defined kbdButtonsOn kbdTrapTable @OldUS; @NewUS kbdOverflowProc kbdTrapProc ] external [ // procedures used MoveBlock ] external [ // statics used OsBuffer lvCursorLink ] static [ kbdButtonsOn = false @NewUS @OldUS DownStrokes UpStrokes ASCIImap LockShift kbdTrapTable kbdOverflowProc kbdTrapProc ] structure [ // shift keys blank word blank word blank bit 4; CtrlBit bit; blank bit 4; LShiftBit bit; blank bit 6 blank bit 7; SwatBit bit; LockShiftBit bit; blank bit 3; RShiftBit bit; blank bit 3 ] let kbdState() be [kbS DownStrokes = table [ #177777; #177777; #173676; #177564; #377 ] UpStrokes = table [ #000000; #000000; #000000; #000000; #377 ] LockShift = table [ #013520; #036740; #013600; #175400; #000 ] ASCIImap = table [ // Unshifted characters, word 0 bs*S+lf; $\*S+$/; $p*S+$-; $k*S+$0; $v*S+$u; $d*S+$7; $e*S+$6; $4*S+$5; // word 1 spr1*S+spr2; $]*S+$'; $,*S+$l; $o*S+$x; $i*S+$9; $a*S+$s; $q*S+$w; $2*S+$3; // word 2 xxx*S+del; $_*S+rtn; $;*S+$.; lshft*S+$z; $b*S+$j; $c*S+ctrl; $f*S+tab; esc*S+$1; // word 3 xxx*S+xxx; spr3*S+rshft; $=*S+$[; space*S+lock; $m*S+$n; $8*S+$h; $y*S+$g; $t*S+$r // buttons mb2*S+mb3; mb1*S+hs5; hs4*S+hs3; hs2*S+hs1; // Shifted characters, word 0 BS*S+LF; $|*S+$?; $P*S+$-; $K*S+$); $V*S+$U; $D*S+$&; $E*S+$~; $$*S+$%; // word 1 SPR1*S+SPR2; $}*S+$"; $<*S+$L; $O*S+$X; $I*S+$(; $A*S+$S; $Q*S+$W; $@*S+$#; // word 2 xxx*S+DEL; $^*S+RTN; $:*S+$>; LSHFT*S+$Z; $B*S+$J; $C*S+CTRL; $F*S+TAB; ESC*S+$!; // word 3 xxx*S+xxx; SPR3*S+RSHFT; $+*S+${; SPACE*S+LOCK; $M*S+$N; $***S+$H; $Y*S+$G; $T*S+$R // buttons MB2*S+MB3; MB1*S+HS5; HS4*S+HS3; HS2*S+HS1; ] ]kbS and KBDHandler() be [kbH MoveBlock(NewUS, Keys, 4) NewUS!4=@buttons if @lvCursorLink then [ test @mouseX ls 0 ifso @mouseX = 0 ifnot if @mouseX gr cursorXmax then @mouseX = cursorXmax @cursorX = @mouseX test @mouseY ls 0 ifso @mouseY = 0 ifnot if @mouseY gr cursorYmax then @mouseY = cursorYmax @cursorY = @mouseY ] for i = 0 to 4 do [ let old = OldUS ! i let new = NewUS ! i let x = old & not new & DownStrokes!i if x ne 0 then KeyAction(x, i, DownStroke) x = not old & new & UpStrokes!i if x ne 0 then KeyAction(x, i, UpStroke) ] let x=OldUS; OldUS=NewUS; NewUS=x ]kbH and KeyAction (b, w, action) be [ka let shm = (NewUS>>LShiftBit eq 0? -1, NewUS>>RShiftBit eq 0? -1, NewUS>>LockShiftBit eq 0? LockShift!w, 0) let m, x = 1, w lshift 4 [ if (b&m) ne 0 then [ // "+ action" below only affects buttons let c = ASCIImap>>InputDatumMap.code^((shm&m) eq 0? x, x+NoOfKeys) + action if (NewUS>>CtrlBit eq 0) & (c ge #100) then c = c & #237 if ((w ls 4) % kbdButtonsOn) & (((kbdTrapTable!(c rshift 4) & 1 lshift (c)) eq 0) % (kbdTrapProc(c) ne false)) then unless kbdPuts(nil, c) do kbdOverflowProc(c) ] m, x = m lshift 1, x+1 ] repeatwhile m ne 0 ]ka and kbdGets(nil) = valof [ let ch = RingGet(OsBuffer) if ch ne -1 resultis ch ] repeat and kbdReset(nil) be [ let x = OsBuffer>>OsBUF.First OsBuffer>>OsBUF.In = x OsBuffer>>OsBUF.Out = x ] and kbdEmpty(nil) = OsBuffer>>OsBUF.In eq OsBuffer>>OsBUF.Out and kbdPuts(nil,x) = valof [ let t = OsBuffer>>OsBUF.In + 1 if t eq OsBuffer>>OsBUF.Last then t = OsBuffer>>OsBUF.First if t eq OsBuffer>>OsBUF.Out then resultis false //Overflow @(OsBuffer>>OsBUF.In) = x OsBuffer>>OsBUF.In = t resultis true ] and RingGet(R,flg; numargs na) = valof [ if R>>OsBUF.Out eq R>>OsBUF.In then resultis -1 let t = R>>OsBUF.Out + 1 if t eq R>>OsBUF.Last then t = R>>OsBUF.First let x = @(R>>OsBUF.Out) if na eq 1 then R>>OsBUF.Out = t resultis x ]