ref: ec35f468e0eba87c9f09cbbe5fa8af2591e6f914
dir: /appl/lib/devpointer.b/
implement Devpointer; include "sys.m"; sys: Sys; include "draw.m"; Pointer: import Draw; include "devpointer.m"; init() { sys = load Sys Sys->PATH; } reader(file: string, posn: chan of ref Pointer, pid: chan of (int, string)) { if(file == nil) file = "/dev/pointer"; dfd := sys->open(file, sys->OREAD); if(dfd == nil){ if(pid != nil){ pid <-= (-1, sys->sprint("cannot open %s: %r", file)); return; } } if(pid != nil) pid <-= (sys->pctl(0, nil), nil); b:= array[Size] of byte; while(sys->read(dfd, b, len b) == Size) posn <-= bytes2ptr(b); } bytes2ptr(b: array of byte): ref Pointer { if(len b < Size || int b[0] != 'm') return nil; x := int string b[1:13]; y := int string b[13:25]; but := int string b[25:37]; msec := int string b[37:49]; return ref Pointer (but, (x, y), msec); } ptr2bytes(p: ref Pointer): array of byte { if(p == nil) return nil; return sys->aprint("m%11d %11d %11d %11ud ", p.xy.x, p.xy.y, p.buttons, p.msec); } srv(c: chan of ref Pointer, f: ref Sys->FileIO) { ptrq := ref Ptrqueue; dummy := chan of (int, int, int, Sys->Rread); sys = load Sys Sys->PATH; for(;;){ r := dummy; if(ptrq.nonempty()) r = f.read; alt{ p := <-c => if(p == nil) exit; ptrq.put(p); (nil, nil, nil, rc) := <-r => if(rc != nil){ alt{ rc <-= (ptr2bytes(ptrq.get()), nil) =>; * =>; } } (nil, nil, nil, rc) := <-f.write => if(rc != nil) rc <-= (0, "read only"); } } } Ptrqueue.put(q: self ref Ptrqueue, s: ref Pointer) { if(q.last != nil && s.buttons == q.last.buttons) *q.last = *s; else{ q.t = s :: q.t; q.last = s; } } Ptrqueue.get(q: self ref Ptrqueue): ref Pointer { s: ref Pointer; h := q.h; if(h == nil){ for(t := q.t; t != nil; t = tl t) h = hd t :: h; q.t = nil; } if(h != nil){ s = hd h; h = tl h; if(h == nil) q.last = nil; } q.h = h; return s; } Ptrqueue.peek(q: self ref Ptrqueue): ref Pointer { s: ref Pointer; if (q.h == nil && q.t == nil) return s; t := q.last; s = q.get(); q.h = s :: q.h; q.last = t; return s; } Ptrqueue.nonempty(q: self ref Ptrqueue): int { return q.h != nil || q.t != nil; }