00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "contiki-net.h"
00036 #include "ctk/vnc-server.h"
00037 #include "ctk/vnc-out.h"
00038 #include "ctk/ctk-vncfont.h"
00039
00040 #include "ctk/ctk-mouse.h"
00041
00042 #include "lib/libconio.h"
00043
00044 #ifdef WITH_AVR
00045 #include <avr/pgmspace.h>
00046 #else
00047 #define memcpy_P memcpy
00048 #endif
00049
00050 #define CHARS_WIDTH LIBCONIO_CONF_SCREEN_WIDTH
00051 #define CHARS_HEIGHT LIBCONIO_CONF_SCREEN_HEIGHT
00052
00053 #define SCREEN_X 10
00054 #define SCREEN_Y 8
00055
00056 #define SCREEN_WIDTH (CHARS_WIDTH * CTK_VNCFONT_WIDTH + 2 * SCREEN_X)
00057 #define SCREEN_HEIGHT (CHARS_HEIGHT * CTK_VNCFONT_HEIGHT + 2 * SCREEN_Y)
00058 #define BORDER_COLOR 0x00
00059 #define SCREEN_COLOR 0x00
00060
00061 #ifndef CH_HOME
00062 #define CH_HOME 0x50
00063 #endif
00064
00065 #ifndef CH_TAB
00066 #define CH_TAB 0x09
00067 #endif
00068
00069
00070 #define BGR(b,g,r) (((b) << 6) | (g) << 3 | (r))
00071
00072
00073 static const u8_t menucolor[] = {
00074 BGR(3,7,7),
00075 BGR(2,6,6),
00076 BGR(0,0,0),
00077 };
00078
00079
00080 static const u8_t activemenucolor[] = {
00081 BGR(0,0,0),
00082 BGR(2,5,5),
00083 BGR(3,7,7),
00084 };
00085
00086 #define W BGR(3,7,7)
00087 #define B BGR(0,0,0)
00088 #define G0 BGR(0,2,2)
00089 #define G1 BGR(1,2,2)
00090 #define G2 BGR(1,3,3)
00091 #define G3 BGR(2,4,4)
00092 #define G4 BGR(2,5,5)
00093 #define G5 BGR(2,6,6)
00094
00095 #define BG BGR(3,4,4)
00096
00097 static const unsigned char backgroundcolor[] = {BG};
00098
00099 static const unsigned char wincol[] =
00100 {BGR(2,5,5),BGR(2,2,2),BGR(0,1,1),G2,G3,G4};
00101
00102 static const unsigned char wincol_f[] =
00103 {BGR(3,7,7),BGR(1,2,2),BGR(0,1,1),G4,G5,W};
00104
00105 static const unsigned char wincol_d[] =
00106 {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0),BGR(2,0,0),BGR(3,2,2),BGR(3,4,4)};
00107
00108 static const unsigned char sepcol[] =
00109 {BGR(2,5,5),BGR(2,6,6),BGR(3,6,6)};
00110 static const unsigned char sepcol_f[] =
00111 {BGR(3,7,7),BGR(3,5,5),BGR(2,5,5)};
00112 static const unsigned char sepcol_d[] =
00113 {BGR(3,7,7),BGR(1,5,7),BGR(0,0,0)};
00114
00115 static const unsigned char labcol[] =
00116 {BGR(2,5,5),BGR(1,3,3),BGR(0,1,1)};
00117 static const unsigned char labcol_f[] =
00118 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0)};
00119 static const unsigned char labcol_d[] =
00120 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0)};
00121
00122
00123 static const unsigned char butcol[] =
00124 {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
00125 BGR(2,5,5),BGR(2,5,5)};
00126 static const unsigned char butcol_w[] =
00127 {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
00128 BGR(2,5,5),BGR(2,5,5)};
00129 static const unsigned char butcol_f[] =
00130 {G5,G4,B,BGR(3,5,5),BGR(3,6,6),BGR(3,7,7),
00131 BGR(3,6,6),BGR(2,5,5)};
00132 static const unsigned char butcol_fw[] =
00133 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0),BGR(1,3,3),BGR(2,7,7),BGR(3,7,7),
00134 BGR(3,6,6),BGR(3,7,7)};
00135 static const unsigned char butcol_d[] =
00136 {BGR(2,3,3),BGR(2,5,5),BGR(3,6,6),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
00137 BGR(3,7,7),BGR(2,5,5)};
00138 static const unsigned char butcol_dw[] =
00139 {BGR(0,0,0),BGR(2,5,5),BGR(3,7,7),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
00140 BGR(3,7,7),BGR(2,5,5)};
00141
00142
00143 static const unsigned char hlcol[] =
00144 {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
00145 static const unsigned char hlcol_w[] =
00146 {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
00147 static const unsigned char hlcol_f[] =
00148 {BGR(3,7,7),BGR(3,5,5),BGR(3,0,0)};
00149 static const unsigned char hlcol_fw[] =
00150 {BGR(3,7,7),BGR(3,6,7),BGR(3,7,7)};
00151 static const unsigned char hlcol_d[] =
00152 {BGR(3,7,7),BGR(3,5,5),BGR(2,0,0)};
00153 static const unsigned char hlcol_dw[] =
00154 {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0)};
00155
00156 static const unsigned char iconcol[] =
00157 {BG,G4,W,B,G1};
00158 static const unsigned char iconcol_w[] =
00159 {BGR(0,1,1),BGR(1,3,3),BGR(3,7,7), B,W};
00160
00161
00162
00163 static const u8_t * const colortheme[] =
00164 {
00165 backgroundcolor,
00166
00167
00168 wincol, wincol, wincol_f, wincol_f, wincol_d, wincol_d,
00169
00170
00171 sepcol, sepcol, sepcol_f, sepcol_f, sepcol_d, sepcol_d,
00172
00173
00174 labcol, labcol, labcol_f, labcol_f, labcol_d, labcol_d,
00175
00176
00177 butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,
00178
00179
00180 hlcol, hlcol_w, hlcol_f, hlcol_fw, hlcol_d, hlcol_dw,
00181
00182
00183 butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,
00184
00185
00186 iconcol, iconcol_w, iconcol, iconcol_w, iconcol, iconcol_w,
00187
00188
00189 menucolor, activemenucolor, activemenucolor
00190 };
00191
00192
00193 static int mouse_x, mouse_y, mouse_button;
00194
00195 #ifdef CTK_VNCSERVER_CONF_SCREEN
00196 static u8_t *screen = CTK_VNCSERVER_CONF_SCREEN;
00197 #else
00198 static u8_t screen[CHARS_WIDTH * CHARS_HEIGHT];
00199 #endif
00200
00201 #ifdef CTK_VNCSERVER_CONF_COLORSCREEN
00202 staitc u8_t *colorscreen = CTK_VNCSERVER_CONF_COLORSCREEN;
00203 #else
00204 static u8_t colorscreen[CHARS_WIDTH * CHARS_HEIGHT];
00205 #endif
00206
00207
00208 #define PRINTF(x)
00209
00210
00211 #define MAX_ICONS CTK_VNCSERVER_CONF_MAX_ICONS
00212 struct ctk_icon *icons[MAX_ICONS];
00213
00214 unsigned char
00215 vnc_out_add_icon(struct ctk_icon *icon)
00216 {
00217 u8_t i;
00218 signed int empty;
00219
00220 empty = -1;
00221 for(i = 0; i < MAX_ICONS; ++i) {
00222 if(icon == icons[i]) {
00223 return i;
00224 }
00225 if(icons[i] == NULL && empty < 0){
00226 empty = i;
00227 }
00228 }
00229
00230 if(empty == -1) {
00231 empty = 0;
00232 }
00233 icons[empty] = icon;
00234 return empty;
00235 }
00236
00237
00238 void
00239 vnc_out_init(void)
00240 {
00241 u16_t i;
00242 for(i = 0; i < CHARS_WIDTH * CHARS_HEIGHT; ++i) {
00243 screen[i] = 0x20;
00244 }
00245 }
00246
00247 void
00248 vnc_out_update_screen(u8_t xpos, u8_t ypos, u8_t c, u8_t color)
00249 {
00250 screen[xpos + ypos * CHARS_WIDTH] = c;
00251 colorscreen[xpos + ypos * CHARS_WIDTH] = color;
00252 }
00253
00254 void
00255 vnc_out_update_area(struct vnc_server_state *vs,
00256 u8_t x, u8_t y, u8_t w, u8_t h)
00257 {
00258 u8_t x2, y2, ax2, ay2;
00259 register struct vnc_server_update *a, *b;
00260
00261 PRINTF(("update_area_connection: should update (%d:%d) (%d:%d)\n",
00262 x, y, w, h));
00263
00264
00265
00266
00267
00268
00269 if(vs->updates_pending != NULL &&
00270 vs->updates_pending->type == VNC_SERVER_UPDATE_FULL) {
00271 PRINTF(("Update_area_connecion: full update already queued...\n"));
00272 return;
00273 }
00274
00275 again:
00276
00277
00278
00279 for(a = vs->updates_pending; a != NULL; a = a->next) {
00280 if(a->x == x && a->y == y &&
00281 a->w == w && a->h == h) {
00282 PRINTF(("Update_area_connecion: found equal area\n"));
00283 return;
00284 }
00285 }
00286
00287
00288
00289
00290 b = NULL;
00291 for(a = vs->updates_pending; a != NULL; a = a->next) {
00292 x2 = x + w;
00293 y2 = y + h;
00294
00295 ax2 = a->x + a->w;
00296 ay2 = a->y + a->h;
00297
00298
00299
00300 #define INSIDE(x,y,x1,y1,x2,y2) ((x1) <= (x) && \
00301 (x2) >= (x) && \
00302 (y1) <= (y) && \
00303 (y2) >= (y))
00304 if(INSIDE(x, y, a->x, a->y, ax2, ay2) ||
00305 INSIDE(x, y2, a->x, a->y, ax2, ay2) ||
00306 INSIDE(x2, y2, a->x, a->y, ax2, ay2) ||
00307 INSIDE(x2, y, a->x, a->y, ax2, ay2) ||
00308 INSIDE(a->x, a->y, x, y, x2, y2) ||
00309 INSIDE(a->x, ay2, x, y, x2, y2) ||
00310 INSIDE(ax2, ay2, x, y, x2, y2) ||
00311 INSIDE(ax2, a->y, x, y, x2, y2)) {
00312
00313
00314 vnc_server_update_remove(vs, a);
00315
00316
00317 vnc_server_update_free(vs, a);
00318
00319 PRINTF(("update_area_connection: inside (%d:%d, %d:%d)\n",
00320 a->x, a->y, ax2, ay2));
00321
00322
00323 #define MIN(a,b) ((a) < (b)? (a): (b))
00324 #define MAX(a,b) ((a) > (b)? (a): (b))
00325 x = MIN(a->x, x);
00326 y = MIN(a->y, y);
00327 ax2 = MAX(ax2, x2);
00328 ay2 = MAX(ay2, y2);
00329 w = ax2 - x;
00330 h = ay2 - y;
00331
00332
00333
00334
00335
00336 PRINTF(("Update_area_connecion: trying larger area (%d:%d) (%d:%d)\n", x, y, w, h));
00337 goto again;
00338 }
00339 if(b != NULL) {
00340 b = b->next;
00341 }
00342 }
00343
00344
00345
00346
00347
00348 a = vnc_server_update_alloc(vs);
00349 if(a == NULL) {
00350 PRINTF(("Update_area_connecion: no free updates, doing full\n"));
00351
00352
00353 while(vs->updates_pending != NULL) {
00354 a = vs->updates_pending;
00355 vnc_server_update_remove(vs, a);
00356 vnc_server_update_free(vs, a);
00357 }
00358
00359 a = vnc_server_update_alloc(vs);
00360 a->type = VNC_SERVER_UPDATE_FULL;
00361 vnc_server_update_add(vs, a);
00362
00363
00364 } else {
00365
00366 PRINTF(("Update_area_connecion: allocated update for (%d:%d) (%d:%d)\n", x, y, w, h));
00367
00368
00369 a->type = VNC_SERVER_UPDATE_PARTS;
00370 a->x = x;
00371 a->y = y;
00372 a->w = w;
00373 a->h = h;
00374 vnc_server_update_add(vs, a);
00375 }
00376 }
00377
00378 static void
00379 init_send_screen(CC_REGISTER_ARG struct vnc_server_state *vs)
00380 {
00381 vs->sendmsg = SEND_SCREEN;
00382 vs->x = vs->y = 0;
00383 vs->x1 = vs->y1 = 0;
00384 vs->x2 = vs->y2 = 0;
00385 vs->w = CHARS_WIDTH;
00386 vs->h = CHARS_HEIGHT;
00387 }
00388
00389 static void
00390 check_updates(CC_REGISTER_ARG struct vnc_server_state *vs)
00391 {
00392
00393 if(vs->state == VNC_RUNNING &&
00394 vs->sendmsg == SEND_NONE &&
00395 vs->updates_current == NULL) {
00396 if(vs->updates_pending != NULL &&
00397 vs->update_requested != 0) {
00398 vs->update_requested = 0;
00399
00400
00401
00402
00403 vs->updates_current = vnc_server_update_dequeue(vs);
00404
00405 if(vs->updates_current->type == VNC_SERVER_UPDATE_PARTS) {
00406 vs->x = vs->x1 = vs->x2 = vs->updates_current->x;
00407 vs->y = vs->y1 = vs->y2 = vs->updates_current->y;
00408 vs->w = vs->updates_current->w;
00409 vs->h = vs->updates_current->h;
00410 vs->sendmsg = SEND_UPDATE;
00411
00412 PRINTF(("New update from (%d:%d) (%d:%d) to (%d:%d)\n",
00413 vs->x, vs->y, vs->x1, vs->y1, vs->x + vs->w,
00414 vs->y + vs->h));
00415 } else if(vs->updates_current->type == VNC_SERVER_UPDATE_FULL) {
00416 init_send_screen(vs);
00417 PRINTF(("New full update\n"));
00418 }
00419 }
00420 }
00421 }
00422
00423 static u8_t tmp[CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT];
00424 static void
00425 makechar(CC_REGISTER_ARG char *ptr, u8_t x, u8_t y)
00426 {
00427 u8_t i, *tmpptr;
00428 register u8_t *colorscheme;
00429 unsigned char *bitmap;
00430 u8_t b, b2;
00431 u8_t xmove, ymove;
00432 unsigned char c, color;
00433
00434 color = colorscreen[x + y * CHARS_WIDTH];
00435 c = screen[x + y * CHARS_WIDTH];
00436
00437 colorscheme = (u8_t *)colortheme[color];
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 if((c & 0x80) != 0) {
00448 xmove = c & 0x0f;
00449 ymove = (c & 0x30) >> 4;
00450
00451 c = colorscreen[x + y * CHARS_WIDTH];
00452
00453 if(icons[c % MAX_ICONS] == NULL) {
00454 c = 0;
00455 }
00456 bitmap = icons[c % MAX_ICONS]->bitmap;
00457
00458 if(bitmap != NULL) {
00459 bitmap = bitmap + ymove * 8*3;
00460 colorscheme = (u8_t *)colortheme[VNC_OUT_ICONCOLOR + (c >> 6)];
00461 switch(xmove) {
00462 case 0:
00463 for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
00464 b = bitmap[i];
00465 *ptr++ = colorscheme[((b >> 7) & 0x01) << 2];
00466 *ptr++ = colorscheme[((b >> 6) & 0x01) << 2];
00467 *ptr++ = colorscheme[((b >> 5) & 0x01) << 2];
00468 *ptr++ = colorscheme[((b >> 4) & 0x01) << 2];
00469 *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
00470 *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];
00471 }
00472 break;
00473 case 1:
00474 for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
00475 b = bitmap[i];
00476 b2 = bitmap[i + 8];
00477 *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
00478 *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];
00479 *ptr++ = colorscheme[((b2 >> 7) & 0x01) << 2];
00480 *ptr++ = colorscheme[((b2 >> 6) & 0x01) << 2];
00481 *ptr++ = colorscheme[((b2 >> 5) & 0x01) << 2];
00482 *ptr++ = colorscheme[((b2 >> 4) & 0x01) << 2];
00483 }
00484 break;
00485 case 2:
00486 for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
00487 b = bitmap[i + 8];
00488 b2 = bitmap[i + 16];
00489 *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
00490 *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];
00491 *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
00492 *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];
00493 *ptr++ = colorscheme[((b2 >> 7) & 0x01) << 2];
00494 *ptr++ = colorscheme[((b2 >> 6) & 0x01) << 2];
00495 }
00496 break;
00497 case 3:
00498 for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
00499 b = bitmap[i + 16];
00500 *ptr++ = colorscheme[((b >> 5) & 0x01) << 2];
00501 *ptr++ = colorscheme[((b >> 4) & 0x01) << 2];
00502 *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
00503 *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];
00504 *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
00505 *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];
00506 }
00507 break;
00508 }
00509 }
00510 } else {
00511 memcpy_P(tmp, &ctk_vncfont[c * (CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT)],
00512 CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT);
00513
00514 tmpptr = tmp;
00515
00516
00517 for(i = 0; i < CTK_VNCFONT_HEIGHT * CTK_VNCFONT_WIDTH; ++i) {
00518 *ptr++ = colorscheme[*tmpptr++];
00519 }
00520 }
00521 }
00522
00523 void
00524 vnc_out_new(CC_REGISTER_ARG struct vnc_server_state *vs)
00525 {
00526 u8_t i;
00527
00528 vs->width = SCREEN_WIDTH;
00529 vs->height = SCREEN_HEIGHT;
00530 vs->x = vs->y = vs->x1 = vs->y1 = vs->x2 = vs->y2 = 0;
00531 vs->w = CHARS_WIDTH;
00532 vs->h = CHARS_HEIGHT;
00533
00534
00535 for(i = 0; i < VNC_SERVER_MAX_UPDATES - 1; ++i) {
00536 vs->updates_pool[i].next = &vs->updates_pool[i + 1];
00537 }
00538 vs->updates_pool[VNC_SERVER_MAX_UPDATES].next = NULL;
00539
00540 vs->updates_free = &vs->updates_pool[0];
00541 vs->updates_pending = vs->updates_current = NULL;
00542 }
00543
00544 void
00545 vnc_out_send_blank(CC_REGISTER_ARG struct vnc_server_state *vs)
00546 {
00547 register struct rfb_fb_update *umsg;
00548 u8_t *ptr;
00549 u16_t len;
00550 u8_t msglen;
00551
00552 vs->x = vs->y = 0;
00553 vs->x2 = vs->y2 = 0;
00554
00555 umsg = (struct rfb_fb_update *)uip_appdata;
00556
00557 umsg->type = RFB_FB_UPDATE;
00558 umsg->rects = UIP_HTONS(2);
00559
00560 ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
00561 len = sizeof(struct rfb_fb_update);
00562
00563 msglen = vnc_server_draw_rect(ptr, 0, 0,
00564 UIP_HTONS(SCREEN_WIDTH),
00565 UIP_HTONS(SCREEN_HEIGHT),
00566 BORDER_COLOR);
00567
00568
00569 ptr += msglen;
00570 len += msglen;
00571
00572 msglen = vnc_server_draw_rect(ptr,
00573 UIP_HTONS(SCREEN_X), UIP_HTONS(SCREEN_Y),
00574 UIP_HTONS(SCREEN_WIDTH - SCREEN_X * 2),
00575 UIP_HTONS(SCREEN_HEIGHT - SCREEN_Y * 2),
00576 SCREEN_COLOR);
00577
00578 uip_send(uip_appdata, len + msglen);
00579
00580 vs->sendmsg = SENT_BLANK;
00581 }
00582
00583 void
00584 vnc_out_send_screen(struct vnc_server_state *vs)
00585 {
00586 vnc_out_send_update(vs);
00587 }
00588
00589 static short tmpbuf[30];
00590 void
00591 vnc_out_send_update(CC_REGISTER_ARG struct vnc_server_state *vs)
00592 {
00593 u8_t x, y, x0;
00594 u8_t msglen;
00595 u16_t len, n;
00596 u8_t *ptr;
00597 struct rfb_fb_update *umsg;
00598 register struct rfb_fb_update_rect_hdr *recthdr;
00599 struct rfb_rre_hdr *rrehdr;
00600 u8_t c, color, lastcolor;
00601 u8_t numblanks;
00602
00603
00604
00605 check_updates(vs);
00606
00607
00608
00609
00610
00611 umsg = (struct rfb_fb_update *)uip_appdata;
00612
00613 umsg->type = RFB_FB_UPDATE;
00614
00615 x0 = vs->x1;
00616 n = 0;
00617 msglen = 0;
00618 ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
00619 len = sizeof(struct rfb_fb_update);
00620
00621
00622 for(y = vs->y1; y < vs->y + vs->h; ++y) {
00623 for(x = x0; x < vs->x + vs->w; ++x) {
00624
00625
00626
00627
00628
00629
00630
00631
00632 c = screen[x + y * CHARS_WIDTH];
00633 numblanks = 0;
00634 lastcolor = color = colorscreen[x + y * CHARS_WIDTH];
00635
00636
00637
00638
00639
00640
00641
00642 while(lastcolor == color &&
00643 c == 0x20 &&
00644 x < vs->x + vs->w) {
00645 ++numblanks;
00646
00647
00648 ++x;
00649 lastcolor = color;
00650 color = colorscreen[x + y * CHARS_WIDTH];
00651 c = screen[x + y * CHARS_WIDTH];
00652 }
00653
00654 if(numblanks > 0) {
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 msglen = sizeof(struct rfb_fb_update_rect_hdr) +
00668 5;
00669
00670 if(msglen >= uip_mss() - len) {
00671
00672
00673
00674
00675 vs->x2 = x - numblanks;
00676 vs->y2 = y;
00677
00678
00679 goto loopend;
00680 }
00681
00682
00683
00684 recthdr = (struct rfb_fb_update_rect_hdr *)tmpbuf;
00685 rrehdr = (struct rfb_rre_hdr *)((char *)recthdr +
00686 sizeof(struct rfb_fb_update_rect_hdr));
00687
00688
00689
00690
00691
00692
00693 recthdr->rect.x = uip_htons(SCREEN_X + (x - numblanks) *
00694 CTK_VNCFONT_WIDTH);
00695 recthdr->rect.y = uip_htons(SCREEN_Y + y * CTK_VNCFONT_HEIGHT);
00696 recthdr->rect.w = uip_htons(CTK_VNCFONT_WIDTH * numblanks);
00697 recthdr->rect.h = UIP_HTONS(CTK_VNCFONT_HEIGHT);
00698 recthdr->encoding[0] =
00699 recthdr->encoding[1] =
00700 recthdr->encoding[2] = 0;
00701 recthdr->encoding[3] = RFB_ENC_RRE;
00702
00703 rrehdr->subrects[0] =
00704 rrehdr->subrects[1] = 0;
00705 rrehdr->bgpixel = colortheme[lastcolor][0];
00706
00707 --x;
00708 } else {
00709
00710
00711
00712
00713
00714
00715
00716 msglen = sizeof(struct rfb_fb_update_rect_hdr) +
00717 CTK_VNCFONT_HEIGHT * CTK_VNCFONT_WIDTH;
00718 if(msglen >= uip_mss() - len) {
00719
00720
00721
00722
00723
00724 vs->x2 = x;
00725 vs->y2 = y;
00726
00727
00728 goto loopend;
00729 }
00730
00731
00732
00733 recthdr = (struct rfb_fb_update_rect_hdr *)tmpbuf;
00734
00735 recthdr->rect.x = uip_htons(SCREEN_X + x * CTK_VNCFONT_WIDTH);
00736 recthdr->rect.y = uip_htons(SCREEN_Y + y * CTK_VNCFONT_HEIGHT);
00737 recthdr->rect.w = UIP_HTONS(CTK_VNCFONT_WIDTH);
00738 recthdr->rect.h = UIP_HTONS(CTK_VNCFONT_HEIGHT);
00739 recthdr->encoding[0] =
00740 recthdr->encoding[1] =
00741 recthdr->encoding[2] = 0;
00742 recthdr->encoding[3] = RFB_ENC_RAW;
00743
00744 makechar((u8_t *)recthdr +
00745 sizeof(struct rfb_fb_update_rect_hdr),
00746 x, y);
00747 }
00748 memcpy(ptr, tmpbuf, msglen);
00749 PRINTF(("Msglen %d (%d:%d)\n", msglen, x, y));
00750 len += msglen;
00751 ptr += msglen;
00752 ++n;
00753 }
00754 x0 = vs->x;
00755 }
00756
00757 loopend:
00758
00759 umsg->rects = uip_htons(n);
00760
00761 if(y == vs->y + vs->h && x == vs->x + vs->w) {
00762 vs->x2 = vs->y2 = 0;
00763 }
00764
00765 if(n > 0) {
00766
00767
00768 uip_send(uip_appdata, len);
00769 }
00770
00771 }
00772
00773 #define NUMKEYS 20
00774 static char keys[NUMKEYS];
00775 static int firstkey, lastkey;
00776
00777
00778 char
00779 vnc_out_keyavail(void)
00780 {
00781 return firstkey != lastkey;
00782 }
00783
00784 char
00785 vnc_out_getkey(void)
00786 {
00787 char key;
00788 key = keys[firstkey];
00789
00790 if(firstkey != lastkey) {
00791 ++firstkey;
00792 if(firstkey >= NUMKEYS) {
00793 firstkey = 0;
00794 }
00795 }
00796
00797 return key;
00798 }
00799
00800 void
00801 vnc_out_key_event(struct vnc_server_state *vs)
00802 {
00803 register struct rfb_key_event *ev;
00804
00805 ev = (struct rfb_key_event *)uip_appdata;
00806
00807 if(ev->down != 0) {
00808 if(vs->sendmsg == SEND_NONE) {
00809 vs->sendmsg = SEND_UPDATE;
00810 }
00811
00812
00813 if(ev->key[2] == 0 ||
00814 (ev->key[2] == 0xff &&
00815 (ev->key[3] == CH_HOME ||
00816 ev->key[3] == CH_TAB ||
00817 ev->key[3] == CH_ESC ||
00818 ev->key[3] == CH_DEL ||
00819 ev->key[3] == CH_ENTER ||
00820 ev->key[3] == CH_CURS_LEFT ||
00821 ev->key[3] == CH_CURS_UP ||
00822 ev->key[3] == CH_CURS_RIGHT ||
00823 ev->key[3] == CH_CURS_DOWN))) {
00824
00825 keys[lastkey] = ev->key[3];
00826 ++lastkey;
00827 if(lastkey >= NUMKEYS) {
00828 lastkey = 0;
00829 }
00830 }
00831 }
00832
00833 check_updates(vs);
00834 }
00835
00836 void
00837 vnc_out_pointer_event(struct vnc_server_state *vs)
00838 {
00839 struct rfb_pointer_event *ev;
00840 u16_t evx, evy;
00841
00842 ev = (struct rfb_pointer_event *)uip_appdata;
00843
00844 evx = uip_htons(ev->x);
00845 evy = uip_htons(ev->y);
00846
00847 if(evx > SCREEN_X && evx < SCREEN_WIDTH - 2 * SCREEN_X &&
00848 evy > SCREEN_Y && evy < SCREEN_HEIGHT - 2 * SCREEN_Y) {
00849
00850 mouse_button = ev->buttonmask & RFB_BUTTON_MASK1;
00851
00852 mouse_x = evx - SCREEN_X;
00853 mouse_y = evy - SCREEN_Y;
00854
00855 check_updates(vs);
00856 }
00857 }
00858
00859 void
00860 vnc_out_acked(CC_REGISTER_ARG struct vnc_server_state *vs)
00861 {
00862 if(vs->state != VNC_RUNNING) {
00863 return;
00864 }
00865 if(vs->sendmsg == SENT_BLANK) {
00866 init_send_screen(vs);
00867 } else if(vs->sendmsg == SEND_BLANK) {
00868
00869 } else if(vs->sendmsg == SEND_SCREEN) {
00870
00871
00872 if(vs->x2 == 0 && vs->y2 == 0) {
00873 vs->sendmsg = SEND_NONE;
00874
00875
00876
00877 if(vs->updates_current != NULL) {
00878 vnc_server_update_free(vs, vs->updates_current);
00879 vs->updates_current = NULL;
00880 }
00881 check_updates(vs);
00882 } else {
00883 vs->x1 = vs->x2;
00884 vs->y1 = vs->y2;
00885 }
00886
00887 } else if(vs->sendmsg == SEND_UPDATE) {
00888 if(vs->x2 == 0 && vs->y2 == 0) {
00889
00890
00891
00892
00893
00894
00895 vs->sendmsg = SEND_NONE;
00896
00897 if(vs->updates_current != NULL) {
00898 vnc_server_update_free(vs, vs->updates_current);
00899 vs->updates_current = NULL;
00900
00901 }
00902 check_updates(vs);
00903 #if 0
00904 if(vs->updaterequest == VNC_SERVER_UPDATE_FULL) {
00905 check_updates(vs);
00906 } else {
00907 vs->updatesptr2 = (vs->updatesptr2 + 1) %
00908 VNC_SERVER_MAX_UPDATES;
00909
00910
00911
00912 if(vs->updatesptr2 == vs->updatesptr) {
00913 vs->updatetype = VNC_SERVER_UPDATE_NONE;
00914 } else {
00915
00916 vs->updaterequest = VNC_SERVER_UPDATE_PARTS;
00917 check_updates(vs);
00918 }
00919 }
00920 #endif
00921 } else {
00922 vs->x1 = vs->x2;
00923 vs->y1 = vs->y2;
00924 }
00925 } else {
00926 vs->sendmsg = SEND_NONE;
00927 }
00928 }
00929
00930 void
00931 vnc_out_poll(struct vnc_server_state *vs)
00932 {
00933
00934
00935
00936 if(vs->state == VNC_RUNNING &&
00937 vs->sendmsg == SEND_NONE) {
00938 check_updates(vs);
00939 vnc_server_send_data(vs);
00940 }
00941 }
00942
00943 #if CTK_CONF_MOUSE_SUPPORT
00944 void
00945 ctk_mouse_init(void)
00946 {
00947
00948 }
00949
00950 unsigned short
00951 ctk_mouse_x(void)
00952 {
00953 return mouse_x;
00954 }
00955
00956 unsigned short
00957 ctk_mouse_y(void)
00958 {
00959 return mouse_y;
00960 }
00961
00962 unsigned char
00963 ctk_mouse_button(void)
00964 {
00965 return mouse_button;
00966 }
00967
00968 void
00969 ctk_mouse_hide(void)
00970 {
00971 }
00972
00973 void
00974 ctk_mouse_show(void)
00975 {
00976 }
00977
00978 #endif