input = cluster is peek, % peek a char getc, % read a char pending, % any input ready ? pending_wait, % wait a while for input copy_wait, % wait for raster_copy done push, % push back on input in_macro, % test if in macro still_macro, % test if still macro chars push_macro, % push macro back on input flush_macro, % flush any macro input bpos, % button position set_highlight, % control highlight chan, % input chan reset rep = null % own data is what is important inputs = KeyPressed + ButtonPressed + ButtonReleased exposures = ExposeRegion + ExposeWindow + ExposeCopy downs = sequence[string]$["\362\361\363\366\360\365\370\370", "\355\351\352\356\350\353\357\357", "\354\342\344\346\341\345\347\347"] ups = sequence[string]$["\322\321\323\326\320\325\330\330", "\315\311\312\316\310\313\317\317", "\314\302\304\306\301\305\307\307"] own peeks: act own rstart: int own copies: int own dones: int own xpos: int own ypos: int own highlight: bool own ev: event peek = proc () returns (char) return(act$top(peeks)) except when bounds: end c: char := getchar() act$addh(peeks, c) return(c) end peek getc = proc () returns (char) if act$empty(peeks) then return(getchar()) else return(act$remh(peeks)) end end getc pending = proc () returns (bool) return(~act$empty(peeks) cor cpending()) end pending pending_wait = proc () returns (bool) if ~act$empty(peeks) then return(true) else for i: int in int$from_to_by(1000, 1, -1) do if cpending() then return(true) end end return(false) end end pending_wait copy_wait = proc () copies := copies + 1 while copies > dones do x_input$mdeq(exposures, ev) if ev.kind = ExposeCopy then dones := dones + 1 else screen$redisplay(ev.win, ev.x, ev.y, ev.x0, ev.y0) end end end copy_wait cpending = proc () returns (bool) while x_input$pending() do x_input$deq(ev) if ev.kind = KeyPressed then act$addh(peeks, x_keymap$getc(ev.value, ev.mask)) except when none: continue when multi (s: string): for i: int in int$from_to_by(string$size(s), 1, -1) do act$addh(peeks, s[i]) end end return(true) end if ev.kind = ButtonPressed then act$addh(peeks, downs[ev.value + 1][ev.mask / 2**12 + 1]) xpos, ypos := screen$position(ev.x, ev.y) act$addh(peeks, esc) return(true) end if ev.kind = ButtonReleased then act$addh(peeks, ups[ev.value + 1][ev.mask / 2**12 + 1]) xpos, ypos := screen$position(ev.x, ev.y) act$addh(peeks, esc) return(true) end if ev.kind = ExposeCopy then dones := dones + 1 elseif ev.kind = UnmapWindow then copies := copies - 1 copy_wait() screen$unmapped(ev.win) elseif ev.kind ~= MouseMoved then screen$redisplay(ev.win, ev.x, ev.y, ev.x0, ev.y0) end end return(false) end cpending getchar = proc () returns (char) rstart := -1 high: bool := false while true do if highlight cand ~high cand ~x_input$pending() then high := true screen$highlight(true) end x_input$deq(ev) if ev.kind = MouseMoved then if highlight then high := true screen$highlight(true) end continue end if high then high := false screen$highlight(false) end if ev.kind = KeyPressed then return(x_keymap$getc(ev.value, ev.mask)) except when none: continue when multi (s: string): for i: int in int$from_to_by(string$size(s), 2, -1) do act$addh(peeks, s[i]) end return(s[1]) end end if ev.kind = ButtonPressed then act$addh(peeks, downs[ev.value + 1][ev.mask / 2**12 + 1]) xpos, ypos := screen$position(ev.x, ev.y) return(esc) end if ev.kind = ButtonReleased then act$addh(peeks, ups[ev.value + 1][ev.mask / 2**12 + 1]) xpos, ypos := screen$position(ev.x, ev.y) return(esc) end if ev.kind = ExposeCopy then dones := dones + 1 elseif ev.kind = UnmapWindow then copies := copies - 1 copy_wait() screen$unmapped(ev.win) else screen$redisplay(ev.win, ev.x, ev.y, ev.x0, ev.y0) end end end getchar push = proc (c: char) if rstart > act$size(peeks) then rstart := -1 end act$addh(peeks, c) end push in_macro = proc () returns (bool) return(rstart >= 0 cand rstart <= act$size(peeks)) end in_macro still_macro = proc () returns (bool) return(rstart >= 0 cand rstart < act$size(peeks)) end still_macro push_macro = proc (s: string) if ~string$empty(s) then z: int := act$size(peeks) if rstart < 0 cor rstart > z then rstart := z end for i: int in int$from_to_by(string$size(s), 1, -1) do act$addh(peeks, s[i]) end end end push_macro flush_macro = proc () returns (string) s: string if rstart >= 0 cand rstart < act$size(peeks) then s := _cvt[_bytevec, string]( _bytevec$create(act$size(peeks) - rstart)) for i: int in int$from_to(1, string$size(s)) do _cvt[string, _bytevec](s)[i] := act$remh(peeks) end else s := "" end rstart := -1 return(s) end flush_macro bpos = proc () returns (int, int) return(xpos, ypos) end bpos set_highlight = proc (flag: bool) highlight := flag end set_highlight chan = proc () returns (_chan) return(_chan$nul()) end chan reset = proc () x_keymap$load("") peeks := act$new() rstart := -1 copies := -1 dones := 0 xpos := 0 ypos := 0 highlight := false ev := x_input$empty_event() end reset end input