Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "vnc.h"
2
 
3
#define SHORT(p) (((p)[0]<<8)|((p)[1]))
4
#define LONG(p) ((SHORT(p)<<16)|SHORT(p+2))
5
 
6
uchar zero[64];
7
 
8
Vnc*
9
vncinit(int fd, int cfd, Vnc *v)
10
{
11
        if(v == nil)
12
		v = mallocz(sizeof(*v), 1);
13
	Binit(&v->in, fd, OREAD);
14
	Binit(&v->out, fd, OWRITE);
15
	v->datafd = fd;
16
	v->ctlfd = cfd;
17
	return v;
18
}
19
 
20
void
21
vncterm(Vnc *v)
22
{
23
	Bterm(&v->out);
24
	Bterm(&v->in);
25
}
26
 
27
void
28
vncflush(Vnc *v)
29
{
30
	if(Bflush(&v->out) < 0){
31
		if(verbose > 1)
32
			fprint(2, "hungup while sending flush: %r\n");
33
		vnchungup(v);
34
	}
35
}
36
 
37
uchar
38
vncrdchar(Vnc *v)
39
{
40
	uchar buf[1];
41
 
42
	vncrdbytes(v, buf, 1);
43
	return buf[0];
44
}
45
 
46
ushort
47
vncrdshort(Vnc *v)
48
{
49
	uchar buf[2];
50
 
51
	vncrdbytes(v, buf, 2);
52
	return SHORT(buf);
53
}
54
 
55
ulong
56
vncrdlong(Vnc *v)
57
{
58
	uchar buf[4];
59
 
60
	vncrdbytes(v, buf, 4);
61
	return LONG(buf);
62
}
63
 
64
Point
65
vncrdpoint(Vnc *v)
66
{
67
	Point p;
68
 
69
	p.x = vncrdshort(v);
70
	p.y = vncrdshort(v);
71
	return p;
72
}
73
 
74
Rectangle
75
vncrdrect(Vnc *v)
76
{
77
	Rectangle r;
78
 
79
	r.min.x = vncrdshort(v);
80
	r.min.y = vncrdshort(v);
81
	r.max.x = r.min.x + vncrdshort(v);
82
	r.max.y = r.min.y + vncrdshort(v);
83
	return r;
84
}
85
 
86
Rectangle
87
vncrdcorect(Vnc *v)
88
{
89
	Rectangle r;
90
 
91
	r.min.x = vncrdchar(v);
92
	r.min.y = vncrdchar(v);
93
	r.max.x = r.min.x + vncrdchar(v);
94
	r.max.y = r.min.y + vncrdchar(v);
95
	return r;
96
}
97
 
98
void
99
vncrdbytes(Vnc *v, void *a, int n)
100
{
101
	if(Bread(&v->in, a, n) != n){
102
		if(verbose > 1)
103
			fprint(2, "hungup while reading\n");
104
		vnchungup(v);
105
	}
106
}
107
 
108
Pixfmt
109
vncrdpixfmt(Vnc *v)
110
{
111
	Pixfmt fmt;
112
	uchar pad[3];
113
 
114
	fmt.bpp = vncrdchar(v);
115
	fmt.depth = vncrdchar(v);
116
	fmt.bigendian = vncrdchar(v);
117
	fmt.truecolor = vncrdchar(v);
118
	fmt.red.max = vncrdshort(v);
119
	fmt.green.max = vncrdshort(v);
120
	fmt.blue.max = vncrdshort(v);
121
	fmt.red.shift = vncrdchar(v);
122
	fmt.green.shift = vncrdchar(v);
123
	fmt.blue.shift = vncrdchar(v);
124
	vncrdbytes(v, pad, 3);
125
	return fmt;
126
}
127
 
128
char*
129
vncrdstring(Vnc *v)
130
{
131
	ulong len;
132
	char *s;
133
 
134
	len = vncrdlong(v);
135
	s = malloc(len+1);
136
	assert(s != nil);
137
 
138
	vncrdbytes(v, s, len);
139
	s[len] = '\0';
140
	return s;
141
}
142
 
143
/*
144
 * on the server side of the negotiation protocol, we read
145
 * the client response and then run the negotiated function.
146
 * in some cases (e.g., TLS) the negotiated function needs to
147
 * use v->datafd directly and be sure that no data has been
148
 * buffered away in the Bio.  since we know the client is waiting
149
 * for our response, it won't have sent any until we respond.
150
 * thus we read the response with vncrdstringx, which goes
151
 * behind bio's back.
152
 */
153
char*
154
vncrdstringx(Vnc *v)
155
{
156
	char tmp[4];
157
	char *s;
158
	ulong len;
159
 
160
	assert(Bbuffered(&v->in) == 0);
161
	if(readn(v->datafd, tmp, 4) != 4){
162
		fprint(2, "cannot rdstringx: %r");
163
		vnchungup(v);
164
	}
165
	len = LONG(tmp);
166
	s = malloc(len+1);
167
	assert(s != nil);
168
	if(readn(v->datafd, s, len) != len){
169
		fprint(2, "cannot rdstringx len %lud: %r", len);
170
		vnchungup(v);
171
	}
172
	s[len] = '\0';
173
	return s;
174
}
175
 
176
void
177
vncwrstring(Vnc *v, char *s)
178
{
179
	ulong len;
180
 
181
	len = strlen(s);
182
	vncwrlong(v, len);
183
	vncwrbytes(v, s, len);
184
}
185
 
186
void
187
vncwrbytes(Vnc *v, void *a, int n)
188
{
189
	if(Bwrite(&v->out, a, n) < 0){
190
		if(verbose > 1) 
191
			fprint(2, "hungup while writing bytes\n");
192
		vnchungup(v);
193
	}
194
}
195
 
196
void
197
vncwrlong(Vnc *v, ulong u)
198
{
199
	uchar buf[4];
200
 
201
	buf[0] = u>>24;
202
	buf[1] = u>>16;
203
	buf[2] = u>>8;
204
	buf[3] = u;
205
	vncwrbytes(v, buf, 4);
206
}
207
 
208
void
209
vncwrshort(Vnc *v, ushort u)
210
{
211
	uchar buf[2];
212
 
213
	buf[0] = u>>8;
214
	buf[1] = u;
215
	vncwrbytes(v, buf, 2);
216
}
217
 
218
void
219
vncwrchar(Vnc *v, uchar c)
220
{
221
	vncwrbytes(v, &c, 1);
222
}
223
 
224
void
225
vncwrpixfmt(Vnc *v, Pixfmt *fmt)
226
{
227
	vncwrchar(v, fmt->bpp);
228
	vncwrchar(v, fmt->depth);
229
	vncwrchar(v, fmt->bigendian);
230
	vncwrchar(v, fmt->truecolor);
231
	vncwrshort(v, fmt->red.max);
232
	vncwrshort(v, fmt->green.max);
233
	vncwrshort(v, fmt->blue.max);
234
	vncwrchar(v, fmt->red.shift);
235
	vncwrchar(v, fmt->green.shift);
236
	vncwrchar(v, fmt->blue.shift);
237
	vncwrbytes(v, zero, 3);
238
}
239
 
240
void
241
vncwrrect(Vnc *v, Rectangle r)
242
{
243
	vncwrshort(v, r.min.x);
244
	vncwrshort(v, r.min.y);
245
	vncwrshort(v, r.max.x-r.min.x);
246
	vncwrshort(v, r.max.y-r.min.y);
247
}
248
 
249
void
250
vncwrpoint(Vnc *v, Point p)
251
{
252
	vncwrshort(v, p.x);
253
	vncwrshort(v, p.y);
254
}
255
 
256
void
257
vnclock(Vnc *v)
258
{
259
	qlock(v);
260
}
261
 
262
void
263
vncunlock(Vnc *v)
264
{
265
	qunlock(v);
266
}
267
 
268
void
269
hexdump(void *a, int n)
270
{
271
	uchar *p, *ep;
272
 
273
	p = a;
274
	ep = p+n;
275
 
276
	for(; p<ep; p++) 
277
		print("%.2ux ", *p);
278
	print("\n");
279
}
280
 
281
void
282
vncgobble(Vnc *v, long n)
283
{
284
	uchar buf[8192];
285
	long m;
286
 
287
	while(n > 0){
288
		m = n;
289
		if(m > sizeof(buf))
290
			m = sizeof(buf);
291
		vncrdbytes(v, buf, m);
292
		n -= m;
293
	}
294
}