summaryrefslogtreecommitdiff
path: root/appl/lib/devpointer.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/lib/devpointer.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/lib/devpointer.b')
-rw-r--r--appl/lib/devpointer.b123
1 files changed, 123 insertions, 0 deletions
diff --git a/appl/lib/devpointer.b b/appl/lib/devpointer.b
new file mode 100644
index 00000000..137f29f6
--- /dev/null
+++ b/appl/lib/devpointer.b
@@ -0,0 +1,123 @@
+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((n := 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, n, 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;
+}