xref: /inferno-os/appl/lib/devpointer.b (revision 4eb166cf184c1f102fb79e31b1465ea3e2021c39)
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