Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "vnc.h"
2
#include "vncv.h"
3
#include <cursor.h>
4
 
5
typedef struct Cursor Cursor;
6
 
7
typedef struct Mouse Mouse;
8
struct Mouse {
9
	int buttons;
10
	Point xy;
11
};
12
 
13
static void
14
resize(Vnc *v, int first)
15
{
16
	int fd;
17
	Point d;
18
 
19
	d = addpt(v->dim, Pt(2*Borderwidth, 2*Borderwidth));
20
	lockdisplay(display);
21
 
22
	if(getwindow(display, Refnone) < 0)
23
		sysfatal("internal error: can't get the window image");
24
 
25
	/*
26
	 * limit the window to at most the vnc server's size
27
	 */
28
	if(first || d.x < Dx(screen->r) || d.y < Dy(screen->r)){
29
		fd = open("/dev/wctl", OWRITE);
30
		if(fd >= 0){
31
			fprint(fd, "resize -dx %d -dy %d", d.x, d.y);
32
			close(fd);
33
		}
34
	}
35
	unlockdisplay(display);
36
}
37
 
38
static void
39
eresized(void)
40
{
41
	resize(vnc, 0);
42
 
43
	requestupdate(vnc, 0);
44
}
45
 
46
static Cursor dotcursor = {
47
	{-7, -7},
48
	{0x00, 0x00,
49
	 0x00, 0x00,
50
	 0x00, 0x00,
51
	 0x00, 0x00, 
52
	 0x03, 0xc0,
53
	 0x07, 0xe0,
54
	 0x0f, 0xf0, 
55
	 0x0f, 0xf0,
56
	 0x0f, 0xf0,
57
	 0x07, 0xe0,
58
	 0x03, 0xc0,
59
	 0x00, 0x00, 
60
	 0x00, 0x00,
61
	 0x00, 0x00,
62
	 0x00, 0x00,
63
	 0x00, 0x00, },
64
	{0x00, 0x00,
65
	 0x00, 0x00,
66
	 0x00, 0x00,
67
	 0x00, 0x00, 
68
	 0x00, 0x00,
69
	 0x03, 0xc0,
70
	 0x07, 0xe0, 
71
	 0x07, 0xe0,
72
	 0x07, 0xe0,
73
	 0x03, 0xc0,
74
	 0x00, 0x00,
75
	 0x00, 0x00, 
76
	 0x00, 0x00,
77
	 0x00, 0x00,
78
	 0x00, 0x00,
79
	 0x00, 0x00, }
80
};
81
 
82
static void
83
mouseevent(Vnc *v, Mouse m)
84
{
85
	vnclock(v);
86
	vncwrchar(v, MMouse);
87
	vncwrchar(v, m.buttons);
88
	vncwrpoint(v, m.xy);
89
	vncflush(v);
90
	vncunlock(v);
91
}
92
 
93
void
94
mousewarp(Point pt)
95
{
96
	pt = addpt(pt, screen->r.min);
97
	if(fprint(mousefd, "m%d %d", pt.x, pt.y) < 0)
98
		fprint(2, "mousefd write: %r\n");
99
}
100
 
101
void
102
initmouse(void)
103
{
104
	char buf[1024];
105
 
106
	snprint(buf, sizeof buf, "%s/mouse", display->devdir);
107
	if((mousefd = open(buf, ORDWR)) < 0)
108
		sysfatal("open %s: %r", buf);
109
}
110
 
111
enum {
112
	EventSize = 1+4*12
113
};
114
void
115
readmouse(Vnc *v)
116
{
117
	int cursorfd, len, n;
118
	char buf[10*EventSize], *start, *end;
119
	uchar curs[2*4+2*2*16];
120
	Cursor *cs;
121
	Mouse m;
122
 
123
	cs = &dotcursor;
124
 
125
	snprint(buf, sizeof buf, "%s/cursor", display->devdir);
126
	if((cursorfd = open(buf, OWRITE)) < 0)
127
		sysfatal("open %s: %r", buf);
128
 
129
	BPLONG(curs+0*4, cs->offset.x);
130
	BPLONG(curs+1*4, cs->offset.y);
131
	memmove(curs+2*4, cs->clr, 2*2*16);
132
	write(cursorfd, curs, sizeof curs);
133
 
134
	resize(v, 1);
135
	requestupdate(vnc, 0);
136
	start = end = buf;
137
	len = 0;
138
	for(;;){
139
		if((n = read(mousefd, end, sizeof(buf) - (end - buf))) < 0)
140
			sysfatal("read mouse failed");
141
 
142
		len += n;
143
		end += n;
144
		while(len >= EventSize){
145
			if(*start == 'm'){
146
				m.xy.x = atoi(start+1);
147
				m.xy.y = atoi(start+1+12);
148
				m.buttons = atoi(start+1+2*12) & 0x1F;
149
				m.xy = subpt(m.xy, screen->r.min);
150
				if(ptinrect(m.xy, Rpt(ZP, v->dim))){
151
					mouseevent(v, m);
152
					/* send wheel button *release* */ 
153
					if ((m.buttons & 0x7) != m.buttons) {
154
						m.buttons &= 0x7;
155
						mouseevent(v, m);
156
					}
157
				}
158
			} else
159
				eresized();
160
 
161
			start += EventSize;
162
			len -= EventSize;
163
		}
164
		if(start - buf > sizeof(buf) - EventSize){
165
			memmove(buf, start, len);
166
			start = buf;
167
			end = start+len;
168
		}
169
	}
170
}
171
 
172
static int snarffd = -1;
173
static ulong snarfvers;
174
 
175
void 
176
writesnarf(Vnc *v, long n)
177
{
178
	uchar buf[8192];
179
	long m;
180
	Biobuf *b;
181
 
182
	if((b = Bopen("/dev/snarf", OWRITE)) == nil){
183
		vncgobble(v, n);
184
		return;
185
	}
186
 
187
	while(n > 0){
188
		m = n;
189
		if(m > sizeof(buf))
190
			m = sizeof(buf);
191
		vncrdbytes(v, buf, m);
192
		n -= m;
193
 
194
		Bwrite(b, buf, m);
195
	}
196
	Bterm(b);
197
	snarfvers++;
198
}
199
 
200
char *
201
getsnarf(int *sz)
202
{
203
	char *snarf, *p;
204
	int n, c;
205
 
206
	*sz =0;
207
	n = 8192;
208
	p = snarf = malloc(n);
209
 
210
	seek(snarffd, 0, 0);
211
	while ((c = read(snarffd, p, n)) > 0){
212
		p += c;
213
		n -= c;
214
		*sz += c;
215
		if (n == 0){
216
			snarf = realloc(snarf, *sz + 8192);
217
			n = 8192;
218
		}
219
	}
220
	return snarf;
221
}
222
 
223
void
224
checksnarf(Vnc *v)
225
{
226
	Dir *dir;
227
	char *snarf;
228
	int len;
229
 
230
	if(snarffd < 0){
231
		snarffd = open("/dev/snarf", OREAD);
232
		if(snarffd < 0)
233
			sysfatal("can't open /dev/snarf: %r");
234
	}
235
 
236
	for(;;){
237
		sleep(1000);
238
 
239
		dir = dirstat("/dev/snarf");
240
		if(dir == nil)	/* this happens under old drawterm */
241
			continue;
242
		if(dir->qid.vers > snarfvers){
243
			snarf = getsnarf(&len);
244
 
245
			vnclock(v);
246
			vncwrchar(v, MCCut);
247
			vncwrbytes(v, "pad", 3);
248
			vncwrlong(v, len);
249
			vncwrbytes(v, snarf, len);
250
			vncflush(v);
251
			vncunlock(v);
252
 
253
			free(snarf);
254
 
255
			snarfvers = dir->qid.vers;
256
		}
257
		free(dir);
258
	}
259
}