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)
66 flushimage(display, 1);
69 unlockdisplay(display);
75 vncwrchar(v, MFrameReq);
76 vncwrchar(v, incremental);
77 vncwrrect(v, Rpt(ZP, Pt(x, y)));
83 clippixbuf(Rectangle r, int maxx, int maxy)
85 int y, h, stride1, stride2;
87 if(r.min.x > maxx || r.min.y > maxy){
96 stride2 = Dx(r) * pixb;
98 stride1 = Dx(r) * pixb;
100 for(y = 0; y < h; y++)
101 memmove(&pixbuf[y * stride1], &pixbuf[y * stride2], stride1);
106 /* must be called with display locked */
108 updatescreen(Rectangle r)
112 lockdisplay(display);
113 if(r.max.x > Dx(screen->r) || r.max.y > Dy(screen->r)){
114 r = clippixbuf(r, Dx(screen->r), Dy(screen->r));
116 unlockdisplay(display);
122 * assume load image fails only because of resize
124 b = Dx(r) * pixb * Dy(r);
125 bb = loadimage(screen, rectaddpt(r, screen->r.min), pixbuf, b);
126 if(bb != b && verbose)
127 fprint(2, "loadimage %d on %R for %R returned %d: %r\n", b, rectaddpt(r, screen->r.min), screen->r, bb);
128 unlockdisplay(display);
132 fillrect(Rectangle r, int stride, uchar *color)
138 for(; y < r.max.y; y++){
139 xe = off + r.max.x * pixb;
140 for(x = off + r.min.x * pixb; x < xe; x += pixb)
141 (*pixcp)(&pixbuf[x], color);
147 loadbuf(Vnc *v, Rectangle r, int stride)
154 for(; y < r.max.y; y++){
155 vncrdbytes(v, linebuf, Dx(r) * vpixb);
156 (*cvtpixels)(&pixbuf[off + r.min.x * pixb], linebuf, Dx(r));
162 for(; y < r.max.y; y++){
163 vncrdbytes(v, &pixbuf[off + r.min.x * pixb], Dx(r) * pixb);
179 return Rect(x, y, x+w, y+h);
184 dohextile(Vnc *v, Rectangle r, int stride)
187 int enc, nsub, sx, sy, w, h, th, tw;
193 for(sy = 0; sy < h; sy += HextileDim){
197 for(sx = 0; sx < w; sx += HextileDim){
202 sr = Rect(sx, sy, sx + tw, sy + th);
204 if(enc & HextileRaw){
205 loadbuf(v, sr, stride);
209 if(enc & HextileBack)
210 vncrdcolor(v, (uchar*)&bg);
211 fillrect(sr, stride, (uchar*)&bg);
213 if(enc & HextileFore)
214 vncrdcolor(v, (uchar*)&fg);
216 if(enc & HextileRects){
218 (*pixcp)((uchar*)&c, (uchar*)&fg);
220 if(enc & HextileCols)
221 vncrdcolor(v, (uchar*)&c);
222 ssr = rectaddpt(hexrect(vncrdshort(v)), sr.min);
223 fillrect(ssr, stride, (uchar*)&c);
237 Rectangle r, subr, maxr;
240 if(!rectinrect(r, Rpt(ZP, v->dim)))
241 sysfatal("bad rectangle from server: %R not in %R", r, Rpt(ZP, v->dim));
242 stride = Dx(r) * pixb;
246 sysfatal("bad rectangle encoding from server");
249 loadbuf(v, Rpt(ZP, Pt(Dx(r), Dy(r))), stride);
255 lockdisplay(display);
256 p = addpt(p, screen->r.min);
257 r = rectaddpt(r, screen->r.min);
258 draw(screen, r, screen, nil, p);
259 unlockdisplay(display);
264 maxr = Rpt(ZP, Pt(Dx(r), Dy(r)));
266 vncrdcolor(v, (uchar*)&color);
267 fillrect(maxr, stride, (uchar*)&color);
269 vncrdcolor(v, (uchar*)&color);
273 subr = vncrdcorect(v);
274 if(!rectinrect(subr, maxr))
275 sysfatal("bad encoding from server");
276 fillrect(subr, stride, (uchar*)&color);
282 dohextile(v, r, stride);
293 pixcp8(uchar *dst, uchar *src)
299 pixcp16(uchar *dst, uchar *src)
301 *(ushort*)dst = *(ushort*)src;
305 pixcp32(uchar *dst, uchar *src)
307 *(ulong*)dst = *(ulong*)src;
311 pixcp24(uchar *dst, uchar *src)
321 if(bpp / 8 * 8 != bpp)
322 sysfatal("can't handle your screen");
327 readfromserver(Vnc *v)
333 vpixb = calcpixb(v->bpp);
334 pixb = calcpixb(screen->depth);
349 sysfatal("can't handle your screen: bad depth %d", pixb);
351 linebuf = malloc(v->dim.x * vpixb);
352 pixbuf = malloc(v->dim.x * pixb * v->dim.y);
353 if(linebuf == nil || pixbuf == nil)
354 sysfatal("can't allocate pix decompression storage");
359 sysfatal("bad message from server");
370 vncrdbytes(v, junk, 3);
382 vncrdbytes(v, junk, 3);