8 "copyrect", EncCopyRect,
10 "hextile", EncHextile,
13 "mousewarp", EncMouseWarp,
14 "desktopsize", EncDesktopSize,
15 "xdesktopsize", EncXDesktopSize,
19 static uchar *linebuf;
22 static void (*pixcp)(uchar*, uchar*);
25 vncsetdim(Vnc *v, Rectangle dim)
27 v->dim = rectsubpt(dim, dim.min);
28 linebuf = realloc(linebuf, v->dim.max.x * vpixb);
29 pixbuf = realloc(pixbuf, v->dim.max.x * pixb * v->dim.max.y);
30 if(linebuf == nil || pixbuf == nil)
31 sysfatal("can't allocate pix decompression storage");
34 unlockdisplay(display);
38 vncrdcolor(Vnc *v, uchar *color)
40 vncrdbytes(v, color, vpixb);
43 (*cvtpixels)(color, color, 1);
50 int enc[16], nenc, i, j, nf;
52 nf = tokenize(encodings, f, nelem(f));
55 for(j=0; j<nelem(enctab); j++)
56 if(strcmp(f[i], enctab[j].name) == 0)
58 if(j == nelem(enctab)){
59 print("warning: unknown encoding %s\n", f[i]);
62 enc[nenc++] = enctab[j].num;
66 vncwrchar(v, MSetEnc);
76 requestupdate(Vnc *v, int incremental)
81 flushimage(display, 1);
82 r = rectsubpt(screen->r, screen->r.min);
83 unlockdisplay(display);
85 if(incremental == 0 && (v->canresize&2)!=0 && !eqrect(r, v->dim)){
86 vncwrchar(v, MSetDesktopSize);
91 vncwrlong(v, v->screen[0].id);
93 vncwrlong(v, v->screen[0].flags);
96 vncwrchar(v, MFrameReq);
97 vncwrchar(v, incremental);
104 clippixbuf(Rectangle r, int maxx, int maxy)
106 int y, h, stride1, stride2;
108 if(r.min.x > maxx || r.min.y > maxy){
117 stride2 = Dx(r) * pixb;
119 stride1 = Dx(r) * pixb;
121 for(y = 0; y < h; y++)
122 memmove(&pixbuf[y * stride1], &pixbuf[y * stride2], stride1);
127 /* must be called with display locked */
129 updatescreen(Rectangle r)
133 lockdisplay(display);
134 if(r.max.x > Dx(screen->r) || r.max.y > Dy(screen->r)){
135 r = clippixbuf(r, Dx(screen->r), Dy(screen->r));
137 unlockdisplay(display);
143 * assume load image fails only because of resize
145 b = Dx(r) * pixb * Dy(r);
146 bb = loadimage(screen, rectaddpt(r, screen->r.min), pixbuf, b);
147 if(bb != b && verbose)
148 fprint(2, "loadimage %d on %R for %R returned %d: %r\n", b, rectaddpt(r, screen->r.min), screen->r, bb);
149 unlockdisplay(display);
153 fillrect(Rectangle r, int stride, uchar *color)
159 for(; y < r.max.y; y++){
160 xe = off + r.max.x * pixb;
161 for(x = off + r.min.x * pixb; x < xe; x += pixb)
162 (*pixcp)(&pixbuf[x], color);
168 loadbuf(Vnc *v, Rectangle r, int stride)
175 for(; y < r.max.y; y++){
176 vncrdbytes(v, linebuf, Dx(r) * vpixb);
177 (*cvtpixels)(&pixbuf[off + r.min.x * pixb], linebuf, Dx(r));
183 for(; y < r.max.y; y++){
184 vncrdbytes(v, &pixbuf[off + r.min.x * pixb], Dx(r) * pixb);
200 return Rect(x, y, x+w, y+h);
205 dohextile(Vnc *v, Rectangle r, int stride)
208 int enc, nsub, sx, sy, w, h, th, tw;
214 for(sy = 0; sy < h; sy += HextileDim){
218 for(sx = 0; sx < w; sx += HextileDim){
223 sr = Rect(sx, sy, sx + tw, sy + th);
225 if(enc & HextileRaw){
226 loadbuf(v, sr, stride);
230 if(enc & HextileBack)
231 vncrdcolor(v, (uchar*)&bg);
232 fillrect(sr, stride, (uchar*)&bg);
234 if(enc & HextileFore)
235 vncrdcolor(v, (uchar*)&fg);
237 if(enc & HextileRects){
239 (*pixcp)((uchar*)&c, (uchar*)&fg);
241 if(enc & HextileCols)
242 vncrdcolor(v, (uchar*)&c);
243 ssr = rectaddpt(hexrect(vncrdshort(v)), sr.min);
244 fillrect(ssr, stride, (uchar*)&c);
258 Rectangle r, subr, maxr;
270 case EncXDesktopSize:
272 n = vncrdlong(v)>>24;
275 v->screen[0].id = vncrdlong(v);
276 v->screen[0].rect = vncrdrect(v);
277 v->screen[0].flags = vncrdlong(v);
283 vncsetdim(v, v->screen[0].rect);
287 if(!rectinrect(r, v->dim))
288 sysfatal("bad rectangle from server: %R not in %R", r, v->dim);
289 maxr = rectsubpt(r, r.min);
290 stride = maxr.max.x * pixb;
294 sysfatal("bad rectangle encoding from server");
297 loadbuf(v, maxr, stride);
303 lockdisplay(display);
304 p = addpt(p, screen->r.min);
305 r = rectaddpt(r, screen->r.min);
306 draw(screen, r, screen, nil, p);
307 unlockdisplay(display);
313 vncrdcolor(v, (uchar*)&color);
314 fillrect(maxr, stride, (uchar*)&color);
316 vncrdcolor(v, (uchar*)&color);
320 subr = vncrdcorect(v);
321 if(!rectinrect(subr, maxr))
322 sysfatal("bad encoding from server");
323 fillrect(subr, stride, (uchar*)&color);
329 dohextile(v, r, stride);
336 pixcp8(uchar *dst, uchar *src)
342 pixcp16(uchar *dst, uchar *src)
344 *(ushort*)dst = *(ushort*)src;
348 pixcp32(uchar *dst, uchar *src)
350 *(ulong*)dst = *(ulong*)src;
354 pixcp24(uchar *dst, uchar *src)
364 if(bpp / 8 * 8 != bpp)
365 sysfatal("can't handle your screen");
370 readfromserver(Vnc *v)
376 vpixb = calcpixb(v->bpp);
377 pixb = calcpixb(screen->depth);
392 sysfatal("can't handle your screen: bad depth %d", pixb);
394 vncsetdim(v, v->dim);
399 sysfatal("bad message from server");
410 vncrdbytes(v, junk, 3);
422 vncrdbytes(v, junk, 3);