Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/unix/drawterm/kern/devmouse.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"u.h"
2
#include	"lib.h"
3
#include	"dat.h"
4
#include	"fns.h"
5
#include	"error.h"
6
 
7
#include	"draw.h"
8
#include	"memdraw.h"
9
#include	"screen.h"
10
 
11
int	mousequeue = 1;
12
 
13
Mouseinfo	mouse;
14
Cursorinfo	cursor;
15
 
16
static int	mousechanged(void*);
17
 
18
enum{
19
	Qdir,
20
	Qcursor,
21
	Qmouse
22
};
23
 
24
Dirtab mousedir[]={
25
	".",		{Qdir, 0, QTDIR},	0,	DMDIR|0555,	
26
	"cursor",	{Qcursor},	0,			0666,
27
	"mouse",	{Qmouse},	0,			0666,
28
};
29
 
30
#define	NMOUSE	(sizeof(mousedir)/sizeof(Dirtab))
31
 
32
static Chan*
33
mouseattach(char *spec)
34
{
35
	return devattach('m', spec);
36
}
37
 
38
static Walkqid*
39
mousewalk(Chan *c, Chan *nc, char **name, int nname)
40
{
41
	return devwalk(c, nc, name, nname, mousedir, NMOUSE, devgen);
42
}
43
 
44
static int
45
mousestat(Chan *c, uchar *db, int n)
46
{
47
	return devstat(c, db, n, mousedir, NMOUSE, devgen);
48
}
49
 
50
static Chan*
51
mouseopen(Chan *c, int omode)
52
{
53
	switch((long)c->qid.path){
54
	case Qdir:
55
		if(omode != OREAD)
56
			error(Eperm);
57
		break;
58
	case Qmouse:
59
		lock(&mouse.lk);
60
		if(mouse.open){
61
			unlock(&mouse.lk);
62
			error(Einuse);
63
		}
64
		mouse.open = 1;
65
		unlock(&mouse.lk);
66
		break;
67
	}
68
	c->mode = openmode(omode);
69
	c->flag |= COPEN;
70
	c->offset = 0;
71
	return c;
72
}
73
 
74
void
75
mouseclose(Chan *c)
76
{
77
	if(!(c->flag&COPEN))
78
		return;
79
 
80
	switch((long)c->qid.path) {
81
	case Qmouse:
82
		lock(&mouse.lk);
83
		mouse.open = 0;
84
		unlock(&mouse.lk);
85
		cursorarrow();
86
	}
87
}
88
 
89
 
90
long
91
mouseread(Chan *c, void *va, long n, vlong offset)
92
{
93
	char buf[4*12+1];
94
	uchar *p;
95
	int i, nn;
96
	ulong msec;
97
/*	static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };	*/
98
 
99
	p = va;
100
	switch((long)c->qid.path){
101
	case Qdir:
102
		return devdirread(c, va, n, mousedir, NMOUSE, devgen);
103
 
104
	case Qcursor:
105
		if(offset != 0)
106
			return 0;
107
		if(n < 2*4+2*2*16)
108
			error(Eshort);
109
		n = 2*4+2*2*16;
110
		lock(&cursor.lk);
111
		BPLONG(p+0, cursor.offset.x);
112
		BPLONG(p+4, cursor.offset.y);
113
		memmove(p+8, cursor.clr, 2*16);
114
		memmove(p+40, cursor.set, 2*16);
115
		unlock(&cursor.lk);
116
		return n;
117
 
118
	case Qmouse:
119
		while(mousechanged(0) == 0)
120
			sleep(&mouse.r, mousechanged, 0);
121
 
122
		lock(&screen.lk);
123
		if(screen.reshaped) {
124
			screen.reshaped = 0;
125
			sprint(buf, "t%11d %11d", 0, ticks());
126
			if(n > 1+2*12)
127
				n = 1+2*12;
128
			memmove(va, buf, n);
129
			unlock(&screen.lk);
130
			return n;
131
		}
132
		unlock(&screen.lk);
133
 
134
		lock(&mouse.lk);
135
		i = mouse.ri;
136
		nn = (mouse.wi + Mousequeue - i) % Mousequeue;
137
		if(nn < 1)
138
			panic("empty mouse queue");
139
		msec = ticks();
140
		while(nn > 1) {
141
			if(mouse.queue[i].msec + Mousewindow > msec)
142
				break;
143
			i = (i+1)%Mousequeue;
144
			nn--;
145
		}
146
		sprint(buf, "m%11d %11d %11d %11d",
147
			mouse.queue[i].xy.x,
148
			mouse.queue[i].xy.y,
149
			mouse.queue[i].buttons,
150
			mouse.queue[i].msec);
151
		mouse.ri = (i+1)%Mousequeue;
152
		unlock(&mouse.lk);
153
		if(n > 1+4*12)
154
			n = 1+4*12;
155
		memmove(va, buf, n);
156
		return n;
157
	}
158
	return 0;
159
}
160
 
161
long
162
mousewrite(Chan *c, void *va, long n, vlong offset)
163
{
164
	char *p;
165
	Point pt;
166
	char buf[64];
167
 
168
	USED(offset);
169
 
170
	p = va;
171
	switch((long)c->qid.path){
172
	case Qdir:
173
		error(Eisdir);
174
 
175
	case Qcursor:
176
		if(n < 2*4+2*2*16){
177
			cursorarrow();
178
		}else{
179
			n = 2*4+2*2*16;
180
			lock(&cursor.lk);
181
			cursor.offset.x = BGLONG(p+0);
182
			cursor.offset.y = BGLONG(p+4);
183
			memmove(cursor.clr, p+8, 2*16);
184
			memmove(cursor.set, p+40, 2*16);
185
			unlock(&cursor.lk);
186
			setcursor();
187
		}
188
		return n;
189
 
190
	case Qmouse:
191
		if(n > sizeof buf-1)
192
			n = sizeof buf -1;
193
		memmove(buf, va, n);
194
		buf[n] = 0;
195
		p = 0;
196
		pt.x = strtoul(buf+1, &p, 0);
197
		if(p == 0)
198
			error(Eshort);
199
		pt.y = strtoul(p, 0, 0);
200
		if(ptinrect(pt, gscreen->r))
201
			mouseset(pt);
202
		return n;
203
	}
204
 
205
	error(Egreg);
206
	return -1;
207
}
208
 
209
int
210
mousechanged(void *a)
211
{
212
	USED(a);
213
 
214
	return mouse.ri != mouse.wi || screen.reshaped;
215
}
216
 
217
Dev mousedevtab = {
218
	'm',
219
	"mouse",
220
 
221
	devreset,
222
	devinit,
223
	devshutdown,
224
	mouseattach,
225
	mousewalk,
226
	mousestat,
227
	mouseopen,
228
	devcreate,
229
	mouseclose,
230
	mouseread,
231
	devbread,
232
	mousewrite,
233
	devbwrite,
234
	devremove,
235
	devwstat,
236
};
237