8 "copyrect", EncCopyRect,
10 "hextile", EncHextile,
13 "mousewarp", EncMouseWarp,
17 static uchar *linebuf;
20 static void (*pixcp)(uchar*, uchar*);
23 vncrdcolor(Vnc *v, uchar *color)
25 vncrdbytes(v, color, vpixb);
28 (*cvtpixels)(color, color, 1);
35 int enc[10], nenc, i, j, nf;
37 nf = tokenize(encodings, f, nelem(f));
40 for(j=0; j<nelem(enctab); j++)
41 if(strcmp(f[i], enctab[j].name) == 0)
43 if(j == nelem(enctab)){
44 print("warning: unknown encoding %s\n", f[i]);
47 enc[nenc++] = enctab[j].num;
51 vncwrchar(v, MSetEnc);
61 requestupdate(Vnc *v, int incremental)
68 unlockdisplay(display);
74 vncwrchar(v, MFrameReq);
75 vncwrchar(v, incremental);
76 vncwrrect(v, Rpt(ZP, Pt(x, y)));
82 clippixbuf(Rectangle r, int maxx, int maxy)
84 int y, h, stride1, stride2;
86 if(r.min.x > maxx || r.min.y > maxy){
95 stride2 = Dx(r) * pixb;
97 stride1 = Dx(r) * pixb;
99 for(y = 0; y < h; y++)
100 memmove(&pixbuf[y * stride1], &pixbuf[y * stride2], stride1);
105 /* must be called with display locked */
107 updatescreen(Rectangle r)
111 lockdisplay(display);
112 if(r.max.x > Dx(screen->r) || r.max.y > Dy(screen->r)){
113 r = clippixbuf(r, Dx(screen->r), Dy(screen->r));
115 unlockdisplay(display);
121 * assume load image fails only because of resize
123 b = Dx(r) * pixb * Dy(r);
124 bb = loadimage(screen, rectaddpt(r, screen->r.min), pixbuf, b);
125 if(bb != b && verbose)
126 fprint(2, "loadimage %d on %R for %R returned %d: %r\n", b, rectaddpt(r, screen->r.min), screen->r, bb);
127 unlockdisplay(display);
131 fillrect(Rectangle r, int stride, uchar *color)
137 for(; y < r.max.y; y++){
138 xe = off + r.max.x * pixb;
139 for(x = off + r.min.x * pixb; x < xe; x += pixb)
140 (*pixcp)(&pixbuf[x], color);
146 loadbuf(Vnc *v, Rectangle r, int stride)
153 for(; y < r.max.y; y++){
154 vncrdbytes(v, linebuf, Dx(r) * vpixb);
155 (*cvtpixels)(&pixbuf[off + r.min.x * pixb], linebuf, Dx(r));
161 for(; y < r.max.y; y++){
162 vncrdbytes(v, &pixbuf[off + r.min.x * pixb], Dx(r) * pixb);
178 return Rect(x, y, x+w, y+h);
183 dohextile(Vnc *v, Rectangle r, int stride)
186 int enc, nsub, sx, sy, w, h, th, tw;
192 for(sy = 0; sy < h; sy += HextileDim){
196 for(sx = 0; sx < w; sx += HextileDim){
201 sr = Rect(sx, sy, sx + tw, sy + th);
203 if(enc & HextileRaw){
204 loadbuf(v, sr, stride);
208 if(enc & HextileBack)
209 vncrdcolor(v, (uchar*)&bg);
210 fillrect(sr, stride, (uchar*)&bg);
212 if(enc & HextileFore)
213 vncrdcolor(v, (uchar*)&fg);
215 if(enc & HextileRects){
217 (*pixcp)((uchar*)&c, (uchar*)&fg);
219 if(enc & HextileCols)
220 vncrdcolor(v, (uchar*)&c);
221 ssr = rectaddpt(hexrect(vncrdshort(v)), sr.min);
222 fillrect(ssr, stride, (uchar*)&c);
236 Rectangle r, subr, maxr;
239 if(r.min.x == r.max.x || r.min.y == r.max.y)
241 if(!rectinrect(r, Rpt(ZP, v->dim)))
242 sysfatal("bad rectangle from server: %R not in %R", r, Rpt(ZP, v->dim));
243 stride = Dx(r) * pixb;
247 sysfatal("bad rectangle encoding from server");
250 loadbuf(v, Rpt(ZP, Pt(Dx(r), Dy(r))), stride);
256 lockdisplay(display);
257 p = addpt(p, screen->r.min);
258 r = rectaddpt(r, screen->r.min);
259 draw(screen, r, screen, nil, p);
260 unlockdisplay(display);
265 maxr = Rpt(ZP, Pt(Dx(r), Dy(r)));
267 vncrdcolor(v, (uchar*)&color);
268 fillrect(maxr, stride, (uchar*)&color);
270 vncrdcolor(v, (uchar*)&color);
274 subr = vncrdcorect(v);
275 if(!rectinrect(subr, maxr))
276 sysfatal("bad encoding from server");
277 fillrect(subr, stride, (uchar*)&color);
283 dohextile(v, r, stride);
294 pixcp8(uchar *dst, uchar *src)
300 pixcp16(uchar *dst, uchar *src)
302 *(ushort*)dst = *(ushort*)src;
306 pixcp32(uchar *dst, uchar *src)
308 *(ulong*)dst = *(ulong*)src;
312 pixcp24(uchar *dst, uchar *src)
322 if(bpp / 8 * 8 != bpp)
323 sysfatal("can't handle your screen");
328 readfromserver(Vnc *v)
334 vpixb = calcpixb(v->bpp);
335 pixb = calcpixb(screen->depth);
350 sysfatal("can't handle your screen: bad depth %d", pixb);
352 linebuf = malloc(v->dim.x * vpixb);
353 pixbuf = malloc(v->dim.x * pixb * v->dim.y);
354 if(linebuf == nil || pixbuf == nil)
355 sysfatal("can't allocate pix decompression storage");
360 sysfatal("bad message from server");
367 flushimage(display, 1);
372 vncrdbytes(v, junk, 3);
384 vncrdbytes(v, junk, 3);