ref: e11c7aa718df592bd69de53ce1d6498cc870f256
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;
}