1implement Devpointer; 2 3include "sys.m"; 4 sys: Sys; 5 6include "draw.m"; 7 Pointer: import Draw; 8 9include "devpointer.m"; 10 11init() 12{ 13 sys = load Sys Sys->PATH; 14} 15 16reader(file: string, posn: chan of ref Pointer, pid: chan of (int, string)) 17{ 18 if(file == nil) 19 file = "/dev/pointer"; 20 dfd := sys->open(file, sys->OREAD); 21 if(dfd == nil){ 22 if(pid != nil){ 23 pid <-= (-1, sys->sprint("cannot open %s: %r", file)); 24 return; 25 } 26 } 27 if(pid != nil) 28 pid <-= (sys->pctl(0, nil), nil); 29 b:= array[Size] of byte; 30 while(sys->read(dfd, b, len b) == Size) 31 posn <-= bytes2ptr(b); 32} 33 34bytes2ptr(b: array of byte): ref Pointer 35{ 36 if(len b < Size || int b[0] != 'm') 37 return nil; 38 x := int string b[1:13]; 39 y := int string b[13:25]; 40 but := int string b[25:37]; 41 msec := int string b[37:49]; 42 return ref Pointer (but, (x, y), msec); 43} 44 45ptr2bytes(p: ref Pointer): array of byte 46{ 47 if(p == nil) 48 return nil; 49 return sys->aprint("m%11d %11d %11d %11ud ", p.xy.x, p.xy.y, p.buttons, p.msec); 50} 51 52srv(c: chan of ref Pointer, f: ref Sys->FileIO) 53{ 54 ptrq := ref Ptrqueue; 55 dummy := chan of (int, int, int, Sys->Rread); 56 sys = load Sys Sys->PATH; 57 58 for(;;){ 59 r := dummy; 60 if(ptrq.nonempty()) 61 r = f.read; 62 alt{ 63 p := <-c => 64 if(p == nil) 65 exit; 66 ptrq.put(p); 67 (nil, nil, nil, rc) := <-r => 68 if(rc != nil){ 69 alt{ 70 rc <-= (ptr2bytes(ptrq.get()), nil) =>; 71 * =>; 72 } 73 } 74 (nil, nil, nil, rc) := <-f.write => 75 if(rc != nil) 76 rc <-= (0, "read only"); 77 } 78 } 79} 80 81Ptrqueue.put(q: self ref Ptrqueue, s: ref Pointer) 82{ 83 if(q.last != nil && s.buttons == q.last.buttons) 84 *q.last = *s; 85 else{ 86 q.t = s :: q.t; 87 q.last = s; 88 } 89} 90 91Ptrqueue.get(q: self ref Ptrqueue): ref Pointer 92{ 93 s: ref Pointer; 94 h := q.h; 95 if(h == nil){ 96 for(t := q.t; t != nil; t = tl t) 97 h = hd t :: h; 98 q.t = nil; 99 } 100 if(h != nil){ 101 s = hd h; 102 h = tl h; 103 if(h == nil) 104 q.last = nil; 105 } 106 q.h = h; 107 return s; 108} 109Ptrqueue.peek(q: self ref Ptrqueue): ref Pointer 110{ 111 s: ref Pointer; 112 if (q.h == nil && q.t == nil) 113 return s; 114 t := q.last; 115 s = q.get(); 116 q.h = s :: q.h; 117 q.last = t; 118 return s; 119} 120Ptrqueue.nonempty(q: self ref Ptrqueue): int 121{ 122 return q.h != nil || q.t != nil; 123} 124