wok-tiny annotate fbvnc-auth/stuff/fbvnc.u @ rev 133

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