wok-stable annotate fbvnc/stuff/fbvnc.u @ rev 11885

pcmanfm2: Improve package integration
author Christophe Lincoln <pankso@slitaz.org>
date Tue Feb 28 14:35:10 2012 +0100 (2012-02-28)
parents
children
rev   line source
pascal@11212 1 --- draw.h
pascal@11212 2 +++ draw.h
pascal@11212 3 @@ -15,5 +15,11 @@
pascal@11212 4 void fb_cmap(void);
pascal@11212 5
pascal@11212 6 /* helper functions */
pascal@11212 7 +struct rgb_conv {
pascal@11212 8 + int rshl, gshl;
pascal@11212 9 + int rskp, gskp, bskp;
pascal@11212 10 + int rmax, gmax, bmax;
pascal@11212 11 +};
pascal@11212 12 +void fill_rgb_conv(int mode, struct rgb_conv *s);
pascal@11212 13 void fb_set(int r, int c, void *mem, int len);
pascal@11212 14 unsigned fb_val(int r, int g, int b);
pascal@11212 15 --- draw.c
pascal@11212 16 +++ draw.c
pascal@11212 17 @@ -10,14 +10,13 @@
pascal@11212 18
pascal@11212 19 #define MIN(a, b) ((a) < (b) ? (a) : (b))
pascal@11212 20 #define MAX(a, b) ((a) > (b) ? (a) : (b))
pascal@11212 21 -#define NLEVELS (1 << 8)
pascal@11212 22 +#define NLEVELS (1 << 16)
pascal@11212 23
pascal@11212 24 static int fd;
pascal@11212 25 static void *fb;
pascal@11212 26 static struct fb_var_screeninfo vinfo;
pascal@11212 27 static struct fb_fix_screeninfo finfo;
pascal@11212 28 -static int bpp;
pascal@11212 29 -static int nr, ng, nb;
pascal@11212 30 +static int bytes_per_pixel;
pascal@11212 31
pascal@11212 32 static int fb_len(void)
pascal@11212 33 {
pascal@11212 34 @@ -28,10 +27,12 @@
pascal@11212 35 {
pascal@11212 36 static unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
pascal@11212 37 struct fb_cmap cmap;
pascal@11212 38 +
pascal@11212 39 if (finfo.visual == FB_VISUAL_TRUECOLOR)
pascal@11212 40 return;
pascal@11212 41 +
pascal@11212 42 cmap.start = 0;
pascal@11212 43 - cmap.len = MAX(nr, MAX(ng, nb));
pascal@11212 44 + cmap.len = NLEVELS;
pascal@11212 45 cmap.red = red;
pascal@11212 46 cmap.green = green;
pascal@11212 47 cmap.blue = blue;
pascal@11212 48 @@ -41,24 +42,39 @@
pascal@11212 49
pascal@11212 50 void fb_cmap(void)
pascal@11212 51 {
pascal@11212 52 - unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
pascal@11212 53 + struct fb_bitfield *color[3] = {
pascal@11212 54 + &vinfo.blue, &vinfo.green, &vinfo.red
pascal@11212 55 + };
pascal@11212 56 + int eye_sensibility[3] = { 2, 0, 1 }; // higher=red, blue, lower=green
pascal@11212 57 struct fb_cmap cmap;
pascal@11212 58 - int i;
pascal@11212 59 + unsigned short map[3][NLEVELS];
pascal@11212 60 + int i, j, n, offset;
pascal@11212 61 +
pascal@11212 62 if (finfo.visual == FB_VISUAL_TRUECOLOR)
pascal@11212 63 return;
pascal@11212 64
pascal@11212 65 - for (i = 0; i < nr; i++)
pascal@11212 66 - red[i] = (65535 / (nr - 1)) * i;
pascal@11212 67 - for (i = 0; i < ng; i++)
pascal@11212 68 - green[i] = (65535 / (ng - 1)) * i;
pascal@11212 69 - for (i = 0; i < nb; i++)
pascal@11212 70 - blue[i] = (65535 / (nb - 1)) * i;
pascal@11212 71 -
pascal@11212 72 + for (i = 0, n = vinfo.bits_per_pixel; i < 3; i++) {
pascal@11212 73 + n -= color[eye_sensibility[i]]->length = n / (3 - i);
pascal@11212 74 + }
pascal@11212 75 + n = (1 << vinfo.bits_per_pixel);
pascal@11212 76 + if (n > NLEVELS)
pascal@11212 77 + n = NLEVELS;
pascal@11212 78 + for (i = offset = 0; i < 3; i++) {
pascal@11212 79 + int length = color[i]->length;
pascal@11212 80 + color[i]->offset = offset;
pascal@11212 81 + for (j = 0; j < n; j++) {
pascal@11212 82 + int k = (j >> offset) << (16 - length);
pascal@11212 83 + if (k == (0xFFFF << (16 - length)))
pascal@11212 84 + k = 0xFFFF;
pascal@11212 85 + map[i][j] = k;
pascal@11212 86 + }
pascal@11212 87 + offset += length;
pascal@11212 88 + }
pascal@11212 89 cmap.start = 0;
pascal@11212 90 - cmap.len = MAX(nr, MAX(ng, nb));
pascal@11212 91 - cmap.red = red;
pascal@11212 92 - cmap.green = green;
pascal@11212 93 - cmap.blue = blue;
pascal@11212 94 + cmap.len = n;
pascal@11212 95 + cmap.red = map[2];
pascal@11212 96 + cmap.green = map[1];
pascal@11212 97 + cmap.blue = map[0];
pascal@11212 98 cmap.transp = NULL;
pascal@11212 99
pascal@11212 100 ioctl(fd, FBIOPUTCMAP, &cmap);
pascal@11212 101 @@ -66,25 +82,26 @@
pascal@11212 102
pascal@11212 103 unsigned fb_mode(void)
pascal@11212 104 {
pascal@11212 105 - return (bpp << 16) | (vinfo.red.length << 8) |
pascal@11212 106 + return (bytes_per_pixel << 16) | (vinfo.red.length << 8) |
pascal@11212 107 (vinfo.green.length << 4) | (vinfo.blue.length);
pascal@11212 108 }
pascal@11212 109
pascal@11212 110 int fb_init(void)
pascal@11212 111 {
pascal@11212 112 + int err = 1;
pascal@11212 113 fd = open(FBDEV_PATH, O_RDWR);
pascal@11212 114 if (fd == -1)
pascal@11212 115 goto failed;
pascal@11212 116 + err++;
pascal@11212 117 if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
pascal@11212 118 goto failed;
pascal@11212 119 + err++;
pascal@11212 120 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
pascal@11212 121 goto failed;
pascal@11212 122 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
pascal@11212 123 - bpp = (vinfo.bits_per_pixel + 7) >> 3;
pascal@11212 124 - nr = 1 << vinfo.red.length;
pascal@11212 125 - ng = 1 << vinfo.blue.length;
pascal@11212 126 - nb = 1 << vinfo.green.length;
pascal@11212 127 + bytes_per_pixel = (vinfo.bits_per_pixel + 7) >> 3;
pascal@11212 128 fb = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
pascal@11212 129 + err++;
pascal@11212 130 if (fb == MAP_FAILED)
pascal@11212 131 goto failed;
pascal@11212 132 fb_cmap_save(1);
pascal@11212 133 @@ -93,7 +110,7 @@
pascal@11212 134 failed:
pascal@11212 135 perror("fb_init()");
pascal@11212 136 close(fd);
pascal@11212 137 - return 1;
pascal@11212 138 + return err;
pascal@11212 139 }
pascal@11212 140
pascal@11212 141 void fb_free(void)
pascal@11212 142 @@ -120,19 +137,30 @@
pascal@11212 143
pascal@11212 144 void fb_set(int r, int c, void *mem, int len)
pascal@11212 145 {
pascal@11212 146 - memcpy(fb_mem(r) + (c + vinfo.xoffset) * bpp, mem, len * bpp);
pascal@11212 147 + memcpy(fb_mem(r) + (c + vinfo.xoffset) * bytes_per_pixel,
pascal@11212 148 + mem, len * bytes_per_pixel);
pascal@11212 149 }
pascal@11212 150
pascal@11212 151 +void fill_rgb_conv(int mode, struct rgb_conv *s)
pascal@11212 152 +{
pascal@11212 153 + int bits;
pascal@11212 154 +
pascal@11212 155 + bits = mode & 0xF; mode >>= 4;
pascal@11212 156 + s->rshl = s->gshl = bits;
pascal@11212 157 + s->bskp = 8 - bits; s->bmax = (1 << bits) -1;
pascal@11212 158 + bits = mode & 0xF; mode >>= 4;
pascal@11212 159 + s->rshl += bits;
pascal@11212 160 + s->gskp = 8 - bits; s->gmax = (1 << bits) -1;
pascal@11212 161 + bits = mode & 0xF;
pascal@11212 162 + s->rskp = 8 - bits; s->rmax = (1 << bits) -1;
pascal@11212 163 +}
pascal@11212 164 +
pascal@11212 165 unsigned fb_val(int r, int g, int b)
pascal@11212 166 {
pascal@11212 167 - switch (fb_mode() & 0x0fff) {
pascal@11212 168 - default:
pascal@11212 169 - fprintf(stderr, "fb_val: unknown fb_mode()\n");
pascal@11212 170 - case 0x0888:
pascal@11212 171 - return (r << 16) | (g << 8) | b;
pascal@11212 172 - case 0x0565:
pascal@11212 173 - return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
pascal@11212 174 - case 0x0233:
pascal@11212 175 - return ((r >> 6) << 6) | ((g >> 5) << 3) | (b >> 5);
pascal@11212 176 - }
pascal@11212 177 + static struct rgb_conv c;
pascal@11212 178 +
pascal@11212 179 + if (c.rshl == 0)
pascal@11212 180 + fill_rgb_conv(fb_mode(), &c);
pascal@11212 181 + return ((r >> c.rskp) << c.rshl) | ((g >> c.gskp) << c.gshl)
pascal@11212 182 + | (b >> c.bskp);
pascal@11212 183 }
pascal@11212 184 --- fbvnc.c
pascal@11212 185 +++ fbvnc.c
pascal@11212 186 @@ -36,13 +36,15 @@
pascal@11212 187
pascal@11212 188 #define VNC_PORT "5900"
pascal@11212 189
pascal@11212 190 -#define MAXRES (1 << 21)
pascal@11212 191 -#define MIN(a, b) ((a) < (b) ? (a) : (b))
pascal@11212 192 +#define MAXRES (1 << 12)
pascal@11212 193
pascal@11212 194 static int cols, rows;
pascal@11212 195 +static int srv_cols, srv_rows;
pascal@11212 196 +static int or, oc;
pascal@11212 197 static int mr, mc; /* mouse position */
pascal@11212 198
pascal@11212 199 static char buf[MAXRES];
pascal@11212 200 +#define MAXPIX (MAXRES/sizeof(fbval_t))
pascal@11212 201
pascal@11212 202 static int vnc_connect(char *addr, char *port)
pascal@11212 203 {
pascal@11212 204 @@ -61,22 +63,26 @@
pascal@11212 205
pascal@11212 206 if (connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == -1) {
pascal@11212 207 close(fd);
pascal@11212 208 - freeaddrinfo(addrinfo);
pascal@11212 209 - return -1;
pascal@11212 210 + fd = -2;
pascal@11212 211 }
pascal@11212 212 freeaddrinfo(addrinfo);
pascal@11212 213 return fd;
pascal@11212 214 }
pascal@11212 215
pascal@11212 216 +static int bpp, vnc_mode;
pascal@11212 217 +static struct rgb_conv format;
pascal@11212 218 static int vnc_init(int fd)
pascal@11212 219 {
pascal@11212 220 - char vncver[] = "RFB 003.003\n";
pascal@11212 221 + static int vncfmt[] = { 0x40888, 0x20565, 0x10233, 0 };
pascal@11212 222 + char vncver[12];
pascal@11212 223 + int i;
pascal@11212 224 +
pascal@11212 225 struct vnc_client_init clientinit;
pascal@11212 226 struct vnc_server_init serverinit;
pascal@11212 227 struct vnc_client_pixelfmt pixfmt_cmd;
pascal@11212 228 int connstat = VNC_CONN_FAILED;
pascal@11212 229
pascal@11212 230 - write(fd, vncver, 12);
pascal@11212 231 + write(fd, "RFB 003.003\n", 12);
pascal@11212 232 read(fd, vncver, 12);
pascal@11212 233
pascal@11212 234 read(fd, &connstat, sizeof(connstat));
pascal@11212 235 @@ -88,68 +94,78 @@
pascal@11212 236 write(fd, &clientinit, sizeof(clientinit));
pascal@11212 237 read(fd, &serverinit, sizeof(serverinit));
pascal@11212 238
pascal@11212 239 - if (fb_init())
pascal@11212 240 - return -1;
pascal@11212 241 - if (FBM_BPP(fb_mode()) != sizeof(fbval_t)) {
pascal@11212 242 - fprintf(stderr, "fbvnc: fbval_t doesn't match fb depth\n");
pascal@11212 243 - exit(1);
pascal@11212 244 - }
pascal@11212 245 - cols = MIN(ntohs(serverinit.w), fb_cols());
pascal@11212 246 - rows = MIN(ntohs(serverinit.h), fb_rows());
pascal@11212 247 + i = fb_init();
pascal@11212 248 + if (i)
pascal@11212 249 + return -1 - i;
pascal@11212 250 + srv_cols = ntohs(serverinit.w);
pascal@11212 251 + srv_rows = ntohs(serverinit.h);
pascal@11212 252 + cols = MIN(srv_cols, fb_cols());
pascal@11212 253 + rows = MIN(srv_rows, fb_rows());
pascal@11212 254 mr = rows / 2;
pascal@11212 255 mc = cols / 2;
pascal@11212 256 + or = oc = 0;
pascal@11212 257
pascal@11212 258 read(fd, buf, ntohl(serverinit.len));
pascal@11212 259 pixfmt_cmd.type = VNC_CLIENT_PIXFMT;
pascal@11212 260 - pixfmt_cmd.format.bpp = 8;
pascal@11212 261 - pixfmt_cmd.format.depth = 8;
pascal@11212 262 pixfmt_cmd.format.bigendian = 0;
pascal@11212 263 pixfmt_cmd.format.truecolor = 1;
pascal@11212 264
pascal@11212 265 - pixfmt_cmd.format.rmax = htons(3);
pascal@11212 266 - pixfmt_cmd.format.gmax = htons(7);
pascal@11212 267 - pixfmt_cmd.format.bmax = htons(7);
pascal@11212 268 - pixfmt_cmd.format.rshl = 0;
pascal@11212 269 - pixfmt_cmd.format.gshl = 2;
pascal@11212 270 - pixfmt_cmd.format.bshl = 5;
pascal@11212 271 + if (bpp < 1)
pascal@11212 272 + bpp = FBM_BPP(fb_mode());
pascal@11212 273 + if (bpp >= 3)
pascal@11212 274 + bpp = 4;
pascal@11212 275 + for (i = 0; bpp <= FBM_BPP(vncfmt[i]); i++)
pascal@11212 276 + vnc_mode = vncfmt[i];
pascal@11212 277 + bpp = FBM_BPP(vnc_mode);
pascal@11212 278 + pixfmt_cmd.format.bpp =
pascal@11212 279 + pixfmt_cmd.format.depth = bpp << 3;
pascal@11212 280
pascal@11212 281 + fill_rgb_conv(FBM_COLORS(vnc_mode), &format);
pascal@11212 282 + pixfmt_cmd.format.rmax = htons(format.rmax);
pascal@11212 283 + pixfmt_cmd.format.gmax = htons(format.gmax);
pascal@11212 284 + pixfmt_cmd.format.bmax = htons(format.bmax);
pascal@11212 285 + pixfmt_cmd.format.rshl = format.rshl;
pascal@11212 286 + pixfmt_cmd.format.gshl = format.gshl;
pascal@11212 287 + pixfmt_cmd.format.bshl = 0;
pascal@11212 288 write(fd, &pixfmt_cmd, sizeof(pixfmt_cmd));
pascal@11212 289 return fd;
pascal@11212 290 }
pascal@11212 291
pascal@11212 292 -static int vnc_free(void)
pascal@11212 293 +static void vnc_free(void)
pascal@11212 294 {
pascal@11212 295 fb_free();
pascal@11212 296 - return 0;
pascal@11212 297 }
pascal@11212 298
pascal@11212 299 -static int vnc_refresh(int fd, int inc)
pascal@11212 300 +static void vnc_refresh(int fd, int inc)
pascal@11212 301 {
pascal@11212 302 struct vnc_client_fbup fbup_req;
pascal@11212 303 fbup_req.type = VNC_CLIENT_FBUP;
pascal@11212 304 fbup_req.inc = inc;
pascal@11212 305 - fbup_req.x = htons(0);
pascal@11212 306 - fbup_req.y = htons(0);
pascal@11212 307 - fbup_req.w = htons(cols);
pascal@11212 308 - fbup_req.h = htons(rows);
pascal@11212 309 + fbup_req.x = htons(oc);
pascal@11212 310 + fbup_req.y = htons(or);
pascal@11212 311 + fbup_req.w = htons(oc + cols);
pascal@11212 312 + fbup_req.h = htons(or + rows);
pascal@11212 313 write(fd, &fbup_req, sizeof(fbup_req));
pascal@11212 314 - return 0;
pascal@11212 315 }
pascal@11212 316
pascal@11212 317 -static void drawfb(char *s, int x, int y, int w, int h)
pascal@11212 318 +static void drawfb(char *s, int x, int y, int w)
pascal@11212 319 {
pascal@11212 320 - fbval_t slice[1 << 14];
pascal@11212 321 - int i, j;
pascal@11212 322 - for (i = 0; i < h; i++) {
pascal@11212 323 - for (j = 0; j < w; j++) {
pascal@11212 324 - int c = *(unsigned char *) &s[i * w + j];
pascal@11212 325 - int r = (c & 0x3) << 6;
pascal@11212 326 - int g = ((c >> 2) & 0x7) << 5;
pascal@11212 327 - int b = ((c >> 5) & 0x7) << 5;
pascal@11212 328 - slice[j] = FB_VAL(r, g, b);
pascal@11212 329 + int mode = fb_mode();
pascal@11212 330 + if (mode != vnc_mode) {
pascal@11212 331 + fbval_t slice[MAXRES];
pascal@11212 332 + unsigned char *byte = (unsigned char *) slice;
pascal@11212 333 + int j;
pascal@11212 334 + int fb_bpp = FBM_BPP(mode);
pascal@11212 335 + for (j = 0; j < w; j++, byte += fb_bpp, s += bpp) {
pascal@11212 336 + fbval_t c = * (fbval_t *) s;
pascal@11212 337 + int r = ((c >> format.rshl) & format.rmax) << format.rskp;
pascal@11212 338 + int g = ((c >> format.gshl) & format.gmax) << format.gskp;
pascal@11212 339 + int b = (c & format.bmax) << format.bskp;
pascal@11212 340 + * (fbval_t *) byte = FB_VAL(r, g, b);
pascal@11212 341 }
pascal@11212 342 - fb_set(y + i, x, slice, w);
pascal@11212 343 + s = (void *) slice;
pascal@11212 344 }
pascal@11212 345 + fb_set(y, x, s, w);
pascal@11212 346 }
pascal@11212 347
pascal@11212 348 static void xread(int fd, void *buf, int len)
pascal@11212 349 @@ -159,54 +175,84 @@
pascal@11212 350 while (nr < len && (n = read(fd, buf + nr, len - nr)) > 0)
pascal@11212 351 nr += n;
pascal@11212 352 if (nr < len) {
pascal@11212 353 - printf("partial vnc read!\n");
pascal@11212 354 - exit(1);
pascal@11212 355 + fprintf(stderr,"partial vnc read!\n");
pascal@11212 356 + exit(99);
pascal@11212 357 }
pascal@11212 358 }
pascal@11212 359
pascal@11212 360 +static void skip(int fd, int len)
pascal@11212 361 +{
pascal@11212 362 + int n;
pascal@11212 363 + while (len > 0 && (n = read(fd, buf, MIN(len, sizeof(buf)))) > 0)
pascal@11212 364 + len -= n;
pascal@11212 365 +}
pascal@11212 366 +
pascal@11212 367 static int vnc_event(int fd)
pascal@11212 368 {
pascal@11212 369 struct vnc_rect uprect;
pascal@11212 370 - char msg[1 << 12];
pascal@11212 371 - struct vnc_server_fbup *fbup = (void *) msg;
pascal@11212 372 - struct vnc_server_cuttext *cuttext = (void *) msg;
pascal@11212 373 - struct vnc_server_colormap *colormap = (void *) msg;
pascal@11212 374 - int j;
pascal@11212 375 - int n;
pascal@11212 376 + union {
pascal@11212 377 + struct vnc_server_fbup fbup;
pascal@11212 378 + struct vnc_server_cuttext cuttext;
pascal@11212 379 + struct vnc_server_colormap colormap;
pascal@11212 380 + } msg;
pascal@11212 381 + int j, n;
pascal@11212 382
pascal@11212 383 - if (read(fd, msg, 1) != 1)
pascal@11212 384 + if (read(fd, &msg.fbup.type, 1) != 1)
pascal@11212 385 return -1;
pascal@11212 386 - switch (msg[0]) {
pascal@11212 387 + switch (msg.fbup.type) {
pascal@11212 388 case VNC_SERVER_FBUP:
pascal@11212 389 - xread(fd, msg + 1, sizeof(*fbup) - 1);
pascal@11212 390 - n = ntohs(fbup->n);
pascal@11212 391 + xread(fd, &msg.fbup.pad, sizeof(msg.fbup) - 1);
pascal@11212 392 + n = ntohs(msg.fbup.n);
pascal@11212 393 for (j = 0; j < n; j++) {
pascal@11212 394 - int x, y, w, h;
pascal@11212 395 + int x, y, w, h, l, i;
pascal@11212 396 xread(fd, &uprect, sizeof(uprect));
pascal@11212 397 + if (uprect.enc != 0) {
pascal@11212 398 + fprintf(stderr,"Encoding not RAW: %d\n",
pascal@11212 399 + ntohl(uprect.enc));
pascal@11212 400 + return -1;
pascal@11212 401 + }
pascal@11212 402 x = ntohs(uprect.x);
pascal@11212 403 y = ntohs(uprect.y);
pascal@11212 404 w = ntohs(uprect.w);
pascal@11212 405 h = ntohs(uprect.h);
pascal@11212 406 - if (x >= cols || x + w > cols)
pascal@11212 407 - return -1;
pascal@11212 408 - if (y >= rows || y + h > rows)
pascal@11212 409 - return -1;
pascal@11212 410 - xread(fd, buf, w * h);
pascal@11212 411 - drawfb(buf, x, y, w, h);
pascal@11212 412 + x -= oc;
pascal@11212 413 + y -= or;
pascal@11212 414 + i = 0;
pascal@11212 415 + l = MIN(w, cols - x);
pascal@11212 416 + if (x < 0) {
pascal@11212 417 + l = MIN(w + x, cols);
pascal@11212 418 + i = MIN(w, -x);
pascal@11212 419 + x = 0;
pascal@11212 420 + }
pascal@11212 421 + if (l < 0)
pascal@11212 422 + l = 0;
pascal@11212 423 + for (; h--; y++) {
pascal@11212 424 + int n = l;
pascal@11212 425 + int xj = x;
pascal@11212 426 + skip(fd, i * bpp);
pascal@11212 427 + while (n > 0) {
pascal@11212 428 + int j = MIN(n, MAXPIX);
pascal@11212 429 + xread(fd, buf, j * bpp);
pascal@11212 430 + if (y >= 0 && y < rows)
pascal@11212 431 + drawfb(buf, xj, y, j);
pascal@11212 432 + xj += j; n -= j;
pascal@11212 433 + }
pascal@11212 434 + skip(fd, (w - l - i) * bpp);
pascal@11212 435 + }
pascal@11212 436 }
pascal@11212 437 break;
pascal@11212 438 case VNC_SERVER_BELL:
pascal@11212 439 break;
pascal@11212 440 case VNC_SERVER_CUTTEXT:
pascal@11212 441 - xread(fd, msg + 1, sizeof(*cuttext) - 1);
pascal@11212 442 - xread(fd, buf, ntohl(cuttext->len));
pascal@11212 443 + xread(fd, &msg.cuttext.pad1, sizeof(msg.cuttext) - 1);
pascal@11212 444 + skip(fd, ntohl(msg.cuttext.len));
pascal@11212 445 break;
pascal@11212 446 case VNC_SERVER_COLORMAP:
pascal@11212 447 - xread(fd, msg + 1, sizeof(*colormap) - 1);
pascal@11212 448 - xread(fd, buf, ntohs(colormap->n) * 3 * 2);
pascal@11212 449 + xread(fd, &msg.colormap.pad, sizeof(msg.colormap) - 1);
pascal@11212 450 + skip(fd, ntohs(msg.colormap.n) * 3 * 2);
pascal@11212 451 break;
pascal@11212 452 default:
pascal@11212 453 - fprintf(stderr, "unknown vnc msg: %d\n", msg[0]);
pascal@11212 454 + fprintf(stderr, "unknown vnc msg: %d\n", msg.fbup.type);
pascal@11212 455 return -1;
pascal@11212 456 }
pascal@11212 457 return 0;
pascal@11212 458 @@ -217,12 +263,31 @@
pascal@11212 459 char ie[3];
pascal@11212 460 struct vnc_client_ratevent me = {VNC_CLIENT_RATEVENT};
pascal@11212 461 int mask = 0;
pascal@11212 462 + int refresh = 2;
pascal@11212 463 if (read(ratfd, &ie, sizeof(ie)) != 3)
pascal@11212 464 return -1;
pascal@11212 465 mc += ie[1];
pascal@11212 466 mr -= ie[2];
pascal@11212 467 - mc = MAX(0, MIN(cols - 1, mc));
pascal@11212 468 - mr = MAX(0, MIN(rows - 1, mr));
pascal@11212 469 + if (mc < oc) {
pascal@11212 470 + if ((oc -= cols / 5) < 0)
pascal@11212 471 + oc = 0;
pascal@11212 472 + }
pascal@11212 473 + else if (mc >= oc + cols && oc + cols < srv_cols) {
pascal@11212 474 + if ((oc += cols / 5) > srv_cols - cols)
pascal@11212 475 + oc = srv_cols - cols;
pascal@11212 476 + }
pascal@11212 477 + else refresh--;
pascal@11212 478 + if (mr < or) {
pascal@11212 479 + if ((or -= rows / 5) < 0)
pascal@11212 480 + or = 0;
pascal@11212 481 + }
pascal@11212 482 + else if (mr >= or + rows && or + rows < srv_rows) {
pascal@11212 483 + if ((or += rows / 5) > srv_rows - rows)
pascal@11212 484 + or = srv_rows - rows;
pascal@11212 485 + }
pascal@11212 486 + else refresh--;
pascal@11212 487 + mc = MAX(oc, MIN(oc + cols - 1, mc));
pascal@11212 488 + mr = MAX(or, MIN(or + rows - 1, mr));
pascal@11212 489 if (ie[0] & 0x01)
pascal@11212 490 mask |= VNC_BUTTON1_MASK;
pascal@11212 491 if (ie[0] & 0x04)
pascal@11212 492 @@ -233,6 +298,8 @@
pascal@11212 493 me.x = htons(mc);
pascal@11212 494 me.mask = mask;
pascal@11212 495 write(fd, &me, sizeof(me));
pascal@11212 496 + if (refresh)
pascal@11212 497 + vnc_refresh(fd, 0);
pascal@11212 498 return 0;
pascal@11212 499 }
pascal@11212 500
pascal@11212 501 @@ -292,12 +359,11 @@
pascal@11212 502 k = 0xff0d;
pascal@11212 503 break;
pascal@11212 504 case 0x0c: /* ^L: redraw */
pascal@11212 505 - if (vnc_refresh(fd, 0))
pascal@11212 506 - return -1;
pascal@11212 507 + vnc_refresh(fd, 0);
pascal@11212 508 default:
pascal@11212 509 k = (unsigned char) key[i];
pascal@11212 510 }
pascal@11212 511 - if (k >= 'A' && k <= 'Z' || strchr(":\"<>?{}|+_()*&^%$#@!~", k))
pascal@11212 512 + if ((k >= 'A' && k <= 'Z') || strchr(":\"<>?{}|+_()*&^%$#@!~", k))
pascal@11212 513 mod[nmod++] = 0xffe1;
pascal@11212 514 if (k >= 1 && k <= 26) {
pascal@11212 515 k = 'a' + k - 1;
pascal@11212 516 @@ -339,40 +405,42 @@
pascal@11212 517 write(STDIN_FILENO, show, strlen(show));
pascal@11212 518 }
pascal@11212 519
pascal@11212 520 -static void mainloop(int vnc_fd, int kbd_fd, int rat_fd)
pascal@11212 521 +static int mainloop(int vnc_fd, int kbd_fd, int rat_fd)
pascal@11212 522 {
pascal@11212 523 struct pollfd ufds[3];
pascal@11212 524 int pending = 0;
pascal@11212 525 int err;
pascal@11212 526 ufds[0].fd = kbd_fd;
pascal@11212 527 - ufds[0].events = POLLIN;
pascal@11212 528 ufds[1].fd = vnc_fd;
pascal@11212 529 - ufds[1].events = POLLIN;
pascal@11212 530 ufds[2].fd = rat_fd;
pascal@11212 531 + ufds[0].events =
pascal@11212 532 + ufds[1].events =
pascal@11212 533 ufds[2].events = POLLIN;
pascal@11212 534 - if (vnc_refresh(vnc_fd, 0))
pascal@11212 535 - return;
pascal@11212 536 + vnc_refresh(vnc_fd, 0);
pascal@11212 537 while (1) {
pascal@11212 538 err = poll(ufds, 3, 500);
pascal@11212 539 if (err == -1 && errno != EINTR)
pascal@11212 540 break;
pascal@11212 541 if (!err)
pascal@11212 542 continue;
pascal@11212 543 + err = -2;
pascal@11212 544 if (ufds[0].revents & POLLIN)
pascal@11212 545 if (kbd_event(vnc_fd, kbd_fd) == -1)
pascal@11212 546 break;
pascal@11212 547 + err--;
pascal@11212 548 if (ufds[1].revents & POLLIN) {
pascal@11212 549 if (vnc_event(vnc_fd) == -1)
pascal@11212 550 break;
pascal@11212 551 pending = 0;
pascal@11212 552 }
pascal@11212 553 + err--;
pascal@11212 554 if (ufds[2].revents & POLLIN)
pascal@11212 555 if (rat_event(vnc_fd, rat_fd) == -1)
pascal@11212 556 break;
pascal@11212 557 if (!pending++)
pascal@11212 558 - if (vnc_refresh(vnc_fd, 1))
pascal@11212 559 - break;
pascal@11212 560 + vnc_refresh(vnc_fd, 1);
pascal@11212 561 }
pascal@11212 562 + return err;
pascal@11212 563 }
pascal@11212 564
pascal@11212 565 int main(int argc, char * argv[])
pascal@11212 566 @@ -380,27 +448,38 @@
pascal@11212 567 char *port = VNC_PORT;
pascal@11212 568 char *host = "127.0.0.1";
pascal@11212 569 struct termios ti;
pascal@11212 570 - int vnc_fd, rat_fd;
pascal@11212 571 + int vnc_fd, rat_fd, status;
pascal@11212 572 +
pascal@11212 573 + if (argc < 2) {
pascal@11212 574 + fprintf(stderr, "Usage : fbvnc [-bpp bits] server [port]\n");
pascal@11212 575 + return 0;
pascal@11212 576 + }
pascal@11212 577 + if (*argv[1] == '-' && argc >= 3) {
pascal@11212 578 + argc -= 2; argv += 2;
pascal@11212 579 + bpp = atoi(argv[0]) >> 3;
pascal@11212 580 + }
pascal@11212 581 if (argc >= 2)
pascal@11212 582 host = argv[1];
pascal@11212 583 if (argc >= 3)
pascal@11212 584 port = argv[2];
pascal@11212 585 - if ((vnc_fd = vnc_connect(host, port)) == -1) {
pascal@11212 586 - fprintf(stderr, "could not connect!\n");
pascal@11212 587 + if ((vnc_fd = vnc_connect(host, port)) < 0) {
pascal@11212 588 + fprintf(stderr, "could not connect! %s %s : %d\n",
pascal@11212 589 + host,port,vnc_fd);
pascal@11212 590 return 1;
pascal@11212 591 }
pascal@11212 592 - if (vnc_init(vnc_fd) == -1) {
pascal@11212 593 - fprintf(stderr, "vnc init failed!\n");
pascal@11212 594 - return 1;
pascal@11212 595 + status = vnc_init(vnc_fd);
pascal@11212 596 + if (status < 0) {
pascal@11212 597 + fprintf(stderr, "vnc init failed! %d\n", status);
pascal@11212 598 + return 2;
pascal@11212 599 }
pascal@11212 600 term_setup(&ti);
pascal@11212 601 rat_fd = open("/dev/input/mice", O_RDONLY);
pascal@11212 602
pascal@11212 603 - mainloop(vnc_fd, 0, rat_fd);
pascal@11212 604 + status = mainloop(vnc_fd, 0, rat_fd);
pascal@11212 605
pascal@11212 606 term_cleanup(&ti);
pascal@11212 607 vnc_free();
pascal@11212 608 close(vnc_fd);
pascal@11212 609 close(rat_fd);
pascal@11212 610 - return 0;
pascal@11212 611 + return 2 - status;
pascal@11212 612 }