/*
 * Copyright (c) 2001, Adam Dunkels
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the uIP TCP/IP stack.
 *
 * $Id: vnc-out.c,v 1.7 2004/09/01 18:18:39 adamdunkels Exp $
 *
 */

#include "uip.h"
#include "vnc-server.h"
#include "vnc-out.h"

#include "libconio.h"

#include "ctk-vncserver-conf.h"

#include "ctk-vncfont.h"

#include "ctk-arch.h"

#include "ctk-mouse.h"

#ifdef WITH_AVR
#include <avr/pgmspace.h>
#else
#define memcpy_P memcpy
#endif /* WITH_AVR */

#define CHARS_WIDTH    LIBCONIO_CONF_SCREEN_WIDTH
#define CHARS_HEIGHT   LIBCONIO_CONF_SCREEN_HEIGHT

#define SCREEN_X       10
#define SCREEN_Y       8

#define SCREEN_WIDTH  (CHARS_WIDTH * CTK_VNCFONT_WIDTH + 2 * SCREEN_X) /*420*/
#define SCREEN_HEIGHT (CHARS_HEIGHT * CTK_VNCFONT_HEIGHT + 2 * SCREEN_Y) /*300*/
#define BORDER_COLOR 0x00
#define SCREEN_COLOR 0x00 /*0xc0*/

#ifndef CH_HOME
#define CH_HOME 0x50
#endif 

#ifndef CH_TAB
#define CH_TAB  0x09
#endif


#define BGR(b,g,r) (((b) << 6) | (g) << 3 | (r))


static const u8_t menucolor[] = {
  BGR(3,7,7), /* Background. */           
  BGR(2,6,6), /* Anti-alias font color. */ 
  BGR(0,0,0), /* Font color. */            
};


static const u8_t activemenucolor[] = {
  BGR(0,0,0), /* Background. */           
  BGR(2,5,5), /* Anti-alias font color. */ 
  BGR(3,7,7), /* Font color. */            
};

#define W  BGR(3,7,7)
#define B  BGR(0,0,0)
#define G0 BGR(0,2,2)
#define G1 BGR(1,2,2)
#define G2 BGR(1,3,3)
#define G3 BGR(2,4,4)
#define G4 BGR(2,5,5)
#define G5 BGR(2,6,6)

#define BG BGR(3,4,4)

static const unsigned char backgroundcolor[] = {BG};

static const unsigned char wincol[] =
  {BGR(2,5,5),BGR(2,2,2),BGR(0,1,1),G2,G3,G4};
  /*  {BGR(2,5,5),BGR(2,2,2),BGR(0,1,1),BGR(1,0,0),BGR(2,0,0),BGR(2,1,1)}; */
static const unsigned char wincol_f[] =
  {BGR(3,7,7),BGR(1,2,2),BGR(0,1,1),G4,G5,W};
  /*  {BGR(3,7,7),BGR(1,2,2),BGR(0,1,1),BGR(2,0,0),BGR(3,2,2),BGR(3,4,4)}; */
static const unsigned char wincol_d[] =
  {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0),BGR(2,0,0),BGR(3,2,2),BGR(3,4,4)};

static const unsigned char sepcol[] =
 {BGR(2,5,5),BGR(2,6,6),BGR(3,6,6)};
static const unsigned char sepcol_f[] =
 {BGR(3,7,7),BGR(3,5,5),BGR(2,5,5)};
static const unsigned char sepcol_d[] =
 {BGR(3,7,7),BGR(1,5,7),BGR(0,0,0)};

static const unsigned char labcol[] =
 {BGR(2,5,5),BGR(1,3,3),BGR(0,1,1)};
static const unsigned char labcol_f[] =
 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0)};
static const unsigned char labcol_d[] =
 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0)};


static const unsigned char butcol[] =
 {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
  BGR(2,5,5),BGR(2,5,5)};
static const unsigned char butcol_w[] =
 {BGR(2,4,4),BGR(1,3,3),BGR(0,1,1),BGR(2,4,4),BGR(2,4,4),BGR(2,4,4),
  BGR(2,5,5),BGR(2,5,5)};
static const unsigned char butcol_f[] =
 {G5,G4,B,BGR(3,5,5),BGR(3,6,6),BGR(3,7,7),
  BGR(3,6,6),BGR(2,5,5)};
static const unsigned char butcol_fw[] =
 {BGR(3,7,7),BGR(3,6,6),BGR(0,0,0),BGR(1,3,3),BGR(2,7,7),BGR(3,7,7),
  BGR(3,6,6),BGR(3,7,7)};
static const unsigned char butcol_d[] =
 {BGR(2,3,3),BGR(2,5,5),BGR(3,6,6),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
  BGR(3,7,7),BGR(2,5,5)};
static const unsigned char butcol_dw[] =
 {BGR(0,0,0),BGR(2,5,5),BGR(3,7,7),BGR(1,3,4),BGR(1,5,6),BGR(2,6,7),
  BGR(3,7,7),BGR(2,5,5)};


static const unsigned char hlcol[] =
 {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
static const unsigned char hlcol_w[] =
 {BGR(2,5,5),BGR(1,3,3),BGR(1,0,0)};
static const unsigned char hlcol_f[] =
 {BGR(3,7,7),BGR(3,5,5),BGR(3,0,0)};
static const unsigned char hlcol_fw[] =
 {BGR(3,7,7),BGR(3,6,7),BGR(3,7,7)};
static const unsigned char hlcol_d[] =
 {BGR(3,7,7),BGR(3,5,5),BGR(2,0,0)};
static const unsigned char hlcol_dw[] =
 {BGR(3,7,7),BGR(1,5,5),BGR(0,0,0)};

static const unsigned char iconcol[] =
  {BG,G4,W,B,G1};
static const unsigned char iconcol_w[] =
 {BGR(0,1,1),BGR(1,3,3),BGR(3,7,7), B,W};



static const u8_t * const colortheme[] =
  {
    backgroundcolor,
    
    /* Window colors */
    wincol, wincol, wincol_f, wincol_f, wincol_d, wincol_d,

    /* Separator colors. */
    sepcol, sepcol, sepcol_f, sepcol_f, sepcol_d, sepcol_d,    

    /* Label colors. */
    labcol, labcol, labcol_f, labcol_f, labcol_d, labcol_d,    

    /* Button colors. */
    butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,    

    /* Hyperlink colors. */
    hlcol, hlcol_w, hlcol_f, hlcol_fw, hlcol_d, hlcol_dw,

    /* Textentry colors. */
    butcol, butcol_w, butcol_f, butcol_fw, butcol_d, butcol_dw,

    /* Icon colors */
    iconcol, iconcol_w, iconcol, iconcol_w, iconcol, iconcol_w,
    
    /* Menu colors. */
    menucolor, activemenucolor, activemenucolor
  };


static int mouse_x, mouse_y, mouse_button;

#ifdef CTK_VNCSERVER_CONF_SCREEN
static u8_t *screen = CTK_VNCSERVER_CONF_SCREEN;
#else
static u8_t screen[CHARS_WIDTH * CHARS_HEIGHT];
#endif

#ifdef CTK_VNCSERVER_CONF_COLORSCREEN
staitc u8_t *colorscreen = CTK_VNCSERVER_CONF_COLORSCREEN;
#else
static u8_t colorscreen[CHARS_WIDTH * CHARS_HEIGHT];
#endif


#define PRINTF(x)

/*-----------------------------------------------------------------------------------*/
#define MAX_ICONS CTK_VNCSERVER_CONF_MAX_ICONS
struct ctk_icon *icons[MAX_ICONS];

unsigned char
vnc_out_add_icon(struct ctk_icon *icon)
{
  u8_t i;
  signed int empty;

  empty = -1;
  for(i = 0; i < MAX_ICONS; ++i) {
    if(icon == icons[i]) {
      return i;
    }
    if(icons[i] == NULL && empty < 0){
      empty = i;
    }
  }

  if(empty == -1) {
    empty = 0;
  }
  icons[empty] = icon;
  return empty;
}

/*-----------------------------------------------------------------------------------*/
void
vnc_out_init(void)
{
  u16_t i;
  for(i = 0; i < CHARS_WIDTH * CHARS_HEIGHT; ++i) {
    screen[i] = 0x20;
  }
}

void
vnc_out_update_screen(u8_t xpos, u8_t ypos, u8_t c, u8_t color)
{
  screen[xpos + ypos * CHARS_WIDTH] = c;
  colorscreen[xpos + ypos * CHARS_WIDTH] = color;
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_update_area(struct vnc_server_state *vs,
		    u8_t x, u8_t y, u8_t w, u8_t h)
{
  u8_t x2, y2, ax2, ay2;
  register struct vnc_server_update *a, *b;

  PRINTF(("update_area_connection: should update (%d:%d) (%d:%d)\n",
	 x, y, w, h));
  
  /* First check if we already have a full update queued. If so, there
     is no need to put this update on the list. If there is a full
     update, it is always the first one on the list, so there is no
     need to go step the list in search for it. */

  if(vs->updates_pending != NULL &&
     vs->updates_pending->type == VNC_SERVER_UPDATE_FULL) {
    PRINTF(("Update_area_connecion: full update already queued...\n"));
    return;
  }

 again:
  
  /* Check that we don't update the same area twice by going through
     the list and search for an update with the same coordinates. */
  for(a = vs->updates_pending; a != NULL; a = a->next) {
    if(a->x == x && a->y == y &&
       a->w == w && a->h == h) {
      PRINTF(("Update_area_connecion: found equal area\n"));
      return;
    }    
  }

  /* Next we check if this update covers an existing update. If so, we
     remove the old update, expand this update so that it covers both
     areas to be updated and run through the process again. */
  b = NULL;
  for(a = vs->updates_pending; a != NULL; a = a->next) {      
    x2 = x + w;
    y2 = y + h;
    
    ax2 = a->x + a->w;
    ay2 = a->y + a->h;

    /* Test the corners of both updates to see if they are inside the
       other area. */
#define INSIDE(x,y,x1,y1,x2,y2) ((x1) <= (x) && \
                                 (x2) >= (x) && \
                                 (y1) <= (y) && \
                                 (y2) >= (y))
    if(INSIDE(x, y, a->x, a->y, ax2, ay2) ||
       INSIDE(x, y2, a->x, a->y, ax2, ay2) ||
       INSIDE(x2, y2, a->x, a->y, ax2, ay2) ||
       INSIDE(x2, y, a->x, a->y, ax2, ay2) ||
       INSIDE(a->x, a->y, x, y, x2, y2) ||
       INSIDE(a->x, ay2, x, y, x2, y2) ||
       INSIDE(ax2, ay2, x, y, x2, y2) ||
       INSIDE(ax2, a->y, x, y, x2, y2)) {

      /* Remove the old update from the list. */
      vnc_server_update_remove(vs, a);

      /* Put it on the free list. */
      vnc_server_update_free(vs, a);

      PRINTF(("update_area_connection: inside (%d:%d, %d:%d)\n",
	     a->x, a->y, ax2, ay2));
      
      /* Find the area that covers both updates. */
#define MIN(a,b) ((a) < (b)? (a): (b))
#define MAX(a,b) ((a) > (b)? (a): (b))
      x = MIN(a->x, x);
      y = MIN(a->y, y);
      ax2 = MAX(ax2, x2);
      ay2 = MAX(ay2, y2);
      w = ax2 - x;
      h = ay2 - y;

      /* This should really be done by a recursive call to this
	 function: update_area_connection(vs, x, y, w, h); but because
	 some compilers might not be able to optimize away the
	 recursive call, we do it using a goto instead. */
      PRINTF(("Update_area_connecion: trying larger area (%d:%d) (%d:%d)\n", x, y, w, h));
      goto again;
    }
    if(b != NULL) {
      b = b->next;
    }
  }
  
  /* Allocate an update object by pulling it off the free list. If
     there are no free objects, we go for a full update instead. */

  /*  a = vs->updates_free;*/
  a = vnc_server_update_alloc(vs);
  if(a == NULL) {
    PRINTF(("Update_area_connecion: no free updates, doing full\n"));
    /* Put all pending updates, except for one, on the free list. Use
       the remaining update as a full update. */
    while(vs->updates_pending != NULL) {
      a = vs->updates_pending;
      vnc_server_update_remove(vs, a);
      vnc_server_update_free(vs, a);
    }

    a = vnc_server_update_alloc(vs);
    a->type = VNC_SERVER_UPDATE_FULL;
    vnc_server_update_add(vs, a);
					

  } else {
    
    PRINTF(("Update_area_connecion: allocated update for (%d:%d) (%d:%d)\n", x, y, w, h));
  /* Else, we put the update object at the end of the pending
     list. */
    a->type = VNC_SERVER_UPDATE_PARTS;
    a->x = x;
    a->y = y;
    a->w = w;
    a->h = h;
    vnc_server_update_add(vs, a);
  }
}
/*-----------------------------------------------------------------------------------*/
static void
init_send_screen(register struct vnc_server_state *vs)
{
  vs->sendmsg = SEND_SCREEN;
  vs->x = vs->y = 0;
  vs->x1 = vs->y1 = 0;
  vs->x2 = vs->y2 = 0;
  vs->w = CHARS_WIDTH;
  vs->h = CHARS_HEIGHT;
}
/*-----------------------------------------------------------------------------------*/
static void
check_updates(register struct vnc_server_state *vs)
{
  
  if(vs->state == VNC_RUNNING &&
     vs->sendmsg == SEND_NONE &&
     vs->updates_current == NULL) {
    if(vs->updates_pending != NULL &&
       vs->update_requested != 0) {
      vs->update_requested = 0;
      /*      vs->updates_current = vs->updates_pending;
      vs->updates_pending = vs->updates_pending->next;
      vs->updates_current->next = NULL;*/

      vs->updates_current = vnc_server_update_dequeue(vs);
      
      if(vs->updates_current->type == VNC_SERVER_UPDATE_PARTS) {
	vs->x = vs->x1 = vs->x2 = vs->updates_current->x;
	vs->y = vs->y1 = vs->y2 = vs->updates_current->y;
	vs->w = vs->updates_current->w;
	vs->h = vs->updates_current->h;
	vs->sendmsg = SEND_UPDATE;
	
	PRINTF(("New update from (%d:%d) (%d:%d) to (%d:%d)\n",
	       vs->x, vs->y, vs->x1, vs->y1, vs->x + vs->w,
	       vs->y + vs->h));
      } else if(vs->updates_current->type == VNC_SERVER_UPDATE_FULL) {
	init_send_screen(vs);
	PRINTF(("New full update\n"));
      }
    }
  }
}
/*-----------------------------------------------------------------------------------*/
static u8_t tmp[CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT];
static void
makechar(CC_REGISTER_ARG char *ptr, u8_t x, u8_t y)
{
  u8_t i, *tmpptr;
  register u8_t *colorscheme;
  unsigned char *bitmap;
  u8_t b, b2;
  u8_t xmove, ymove;
  unsigned char c, color;

  color = colorscreen[x + y * CHARS_WIDTH];
  c = screen[x + y * CHARS_WIDTH];

  colorscheme = (u8_t *)colortheme[color];
      
  /* First check if the character is a special icon character. These
     are to be interpreted in a special manner: the first character of
     the icon (the top left corner) has the highest bit set, but not
     bit 6. All other characters have bit 6 set, and also count the
     number of positions away from the top left corner. Only the top
     left corner contains enough information to identify the icon, all
     other chars only contain the number of steps to reach the
     identifying icon. */
  if((c & 0x80) != 0) {
    xmove = c & 0x0f;
    ymove = (c & 0x30) >> 4;
    
    c = colorscreen[x + y * CHARS_WIDTH];

    if(icons[c % MAX_ICONS] == NULL) {
      c = 0;
    }
    bitmap = icons[c % MAX_ICONS]->bitmap;

    if(bitmap != NULL) {
      bitmap = bitmap + ymove * 8*3;
      colorscheme = (u8_t *)colortheme[VNC_OUT_ICONCOLOR + (c >> 6)];
      switch(xmove) {
      case 0:
	for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
	  b = bitmap[i];
	  *ptr++ = colorscheme[((b >> 7) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 6) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 5) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 4) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];		
	}
	break;
      case 1:
	for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
	  b = bitmap[i];
	  b2 = bitmap[i + 8];
	  *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 7) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 6) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 5) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 4) & 0x01) << 2];		
	}
	break;
      case 2:
	for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
	  b = bitmap[i + 8];
	  b2 = bitmap[i + 16];
	  *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 7) & 0x01) << 2];
	  *ptr++ = colorscheme[((b2 >> 6) & 0x01) << 2];		
	}
	break;
      case 3:
	for(i = 0; i < CTK_VNCFONT_HEIGHT; ++i) {
	  b = bitmap[i + 16];
	  *ptr++ = colorscheme[((b >> 5) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 4) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 3) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 2) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 1) & 0x01) << 2];
	  *ptr++ = colorscheme[((b >> 0) & 0x01) << 2];		
	}
	break;
      }
    }
  } else {
    memcpy_P(tmp, &ctk_vncfont[c * (CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT)],
	     CTK_VNCFONT_WIDTH * CTK_VNCFONT_HEIGHT);
    
    tmpptr = tmp;

    
    for(i = 0; i < CTK_VNCFONT_HEIGHT * CTK_VNCFONT_WIDTH; ++i) {
      *ptr++ = colorscheme[*tmpptr++];
    }
  }
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_new(register struct vnc_server_state *vs)
{
  u8_t i;
  
  vs->width = SCREEN_WIDTH;
  vs->height = SCREEN_HEIGHT;
  vs->x = vs->y = vs->x1 = vs->y1 = vs->x2 = vs->y2 = 0;
  vs->w = CHARS_WIDTH;
  vs->h = CHARS_HEIGHT;

  /* Initialize the linked list of updates. */
  for(i = 0; i < VNC_SERVER_MAX_UPDATES - 1; ++i) {
    vs->updates_pool[i].next = &vs->updates_pool[i + 1];    
  }
  vs->updates_pool[VNC_SERVER_MAX_UPDATES].next = NULL;

  vs->updates_free = &vs->updates_pool[0];
  vs->updates_pending = vs->updates_current = NULL;
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_send_blank(register struct vnc_server_state *vs)
{
  register struct rfb_fb_update *umsg;
  u8_t *ptr;
  u16_t len;
  u8_t msglen;
      
  vs->x = vs->y = 0;
  vs->x2 = vs->y2 = 0;
	  
  umsg = (struct rfb_fb_update *)uip_appdata;
  
  umsg->type = RFB_FB_UPDATE;
  umsg->rects = HTONS(2);

  ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
  len = sizeof(struct rfb_fb_update);
  
  msglen = vnc_server_draw_rect(ptr, 0, 0,
				HTONS(SCREEN_WIDTH),
				HTONS(SCREEN_HEIGHT),
				BORDER_COLOR);

  
  ptr += msglen;
  len += msglen;

  msglen = vnc_server_draw_rect(ptr,
				HTONS(SCREEN_X), HTONS(SCREEN_Y),
				HTONS(SCREEN_WIDTH - SCREEN_X * 2),
				HTONS(SCREEN_HEIGHT - SCREEN_Y * 2),
				SCREEN_COLOR);

  uip_send(uip_appdata, len + msglen);

  vs->sendmsg = SENT_BLANK;
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_send_screen(struct vnc_server_state *vs)
{
  vnc_out_send_update(vs);
}
/*-----------------------------------------------------------------------------------*/
static short tmpbuf[30];
void
vnc_out_send_update(register struct vnc_server_state *vs)
{
  u8_t x, y, x0;
  u8_t msglen;
  u16_t len, n;
  u8_t *ptr;
  struct rfb_fb_update *umsg;
  register struct rfb_fb_update_rect_hdr *recthdr;
  struct rfb_rre_hdr *rrehdr;
  u8_t c, color, lastcolor;
  u8_t numblanks;

  /* First, check if we need to feed the update function with a new
     pending update. */
  check_updates(vs);

  /*  PRINTF(("Sending Update from (%d:%d) (%d:%d) to (%d:%d)\n",
	 vs->x, vs->y, vs->x1, vs->y1, vs->x + vs->w,
	 vs->y + vs->h));*/
  
  umsg = (struct rfb_fb_update *)uip_appdata;

  umsg->type = RFB_FB_UPDATE;

  x0 = vs->x1;
  n = 0;
  msglen = 0;
  ptr = (u8_t *)umsg + sizeof(struct rfb_fb_update);
  len = sizeof(struct rfb_fb_update);
  
  /* Loop over all characters that are covered by this update. */
  for(y = vs->y1; y < vs->y + vs->h; ++y) {
    for(x = x0; x < vs->x + vs->w; ++x) {


      /* First check if there are any blank space characters, and if
	 so, find out how many of them there are in a row. Instead of
	 sending the individual space characters as raw bitmaps, we
	 can send the entire string of blanks as a single color
	 rectangle instead. */
      
      c = screen[x + y * CHARS_WIDTH];
      numblanks = 0;
      lastcolor = color = colorscreen[x + y * CHARS_WIDTH];

      /* If the character is a blank, we continue reading characters
	 until we find one that has a different color, or one that is
	 not a blank. We must keep within the update rectangle, so we
	 make sure that the "x" variable does not increase beyond the
	 edge. The "numblanks" variable is used to keep track of how
	 many blank characters we have found. */
      while(lastcolor == color &&
	    c == 0x20 &&
	    x < vs->x + vs->w) {
	++numblanks;

	
	++x;
	lastcolor = color;
	color = colorscreen[x + y * CHARS_WIDTH];
	c = screen[x + y * CHARS_WIDTH];
      }

      if(numblanks > 0) {
	
	/*	PRINTF(("Found %d blanks (%d:%d -> %d:%d)\n",
		numblanks, x - numblanks, y, x, y));*/
	
	/* There were one or more blank characters, so we send out a
	   single color rectangle with the right width. But first we
	   make sure that there is enough space in the current TCP
	   segment to put the rectangle. If there isn't we have to
	   backtrack the "x" variable to where we found the first
	   blank character so that the next TCP segment will be able
	   to update this area instead. */	

	msglen = sizeof(struct rfb_fb_update_rect_hdr) +
	  /*sizeof(struct rfb_rre_hdr)*/5;

	if(msglen >= uip_mss() - len) {
	  /*	  PRINTF(("Not enouch space for blanks (%d, left %d)\n",
		  msglen, uip_mss() - len));*/
	  /* There is not enough space in the segment, so we remember
	     where we were ... */
	  vs->x2 = x - numblanks;
	  vs->y2 = y;

	  /* ... and we break out of the loop. */
	  goto loopend;	  
	}

	/* We construct a rectangle with the right width and color. */
	/*	recthdr = (struct rfb_fb_update_rect_hdr *)ptr;*/
	recthdr = (struct rfb_fb_update_rect_hdr *)tmpbuf;
	rrehdr = (struct rfb_rre_hdr *)((char *)recthdr +
		 sizeof(struct rfb_fb_update_rect_hdr));

	/*	PRINTF(("Blankign (%d:%d) to (%d:%d)\n",
	       (x - numblanks) * CTK_VNCFONT_WIDTH,
	       y * CTK_VNCFONT_HEIGHT,
	       CTK_VNCFONT_WIDTH * numblanks,
	       CTK_VNCFONT_HEIGHT));*/
	recthdr->rect.x = htons(SCREEN_X + (x - numblanks) *
				CTK_VNCFONT_WIDTH);
	recthdr->rect.y = htons(SCREEN_Y + y * CTK_VNCFONT_HEIGHT);
	recthdr->rect.w = htons(CTK_VNCFONT_WIDTH * numblanks);
	recthdr->rect.h = HTONS(CTK_VNCFONT_HEIGHT);
	recthdr->encoding[0] =
	  recthdr->encoding[1] =
	  recthdr->encoding[2] = 0;
	recthdr->encoding[3] = RFB_ENC_RRE;
	
	rrehdr->subrects[0] =
	  rrehdr->subrects[1] = 0;
	rrehdr->bgpixel = colortheme[lastcolor][0];

	--x;
      } else {

	/* So there were no blank characters. */

	/*	PRINTF(("An char at (%d:%d)\n", x, y));*/
	/* First we must make sure that there is enough space in the
	   outgoing TCP segment. */

	msglen = sizeof(struct rfb_fb_update_rect_hdr) +
	  CTK_VNCFONT_HEIGHT * CTK_VNCFONT_WIDTH;
	if(msglen >= uip_mss() - len) {
	  /*	  PRINTF(("Not enouch space for char (%d, left %d)\n",
		  msglen, uip_mss() - len));*/
	  
	  /* There is not enough space in the segment, so we remember
	     where we were ... */
	  vs->x2 = x;
	  vs->y2 = y;

	  /* ... and we break out of the loop. */
	  goto loopend;	  
	}

	/*	PRINTF(("ptr %p\n",ptr);*/
	/*	recthdr = (struct rfb_fb_update_rect_hdr *)ptr;*/
	recthdr = (struct rfb_fb_update_rect_hdr *)tmpbuf;

	recthdr->rect.x = htons(SCREEN_X + x * CTK_VNCFONT_WIDTH);
	recthdr->rect.y = htons(SCREEN_Y + y * CTK_VNCFONT_HEIGHT);
	recthdr->rect.w = HTONS(CTK_VNCFONT_WIDTH);
	recthdr->rect.h = HTONS(CTK_VNCFONT_HEIGHT);
	recthdr->encoding[0] =
	  recthdr->encoding[1] =
	  recthdr->encoding[2] = 0;
	recthdr->encoding[3] = RFB_ENC_RAW;

	makechar((u8_t *)recthdr +
		 sizeof(struct rfb_fb_update_rect_hdr),
		 x, y);
      }
      memcpy(ptr, tmpbuf, msglen);
      PRINTF(("Msglen %d (%d:%d)\n", msglen, x, y));
      len += msglen;
      ptr += msglen;
      ++n;
    }
    x0 = vs->x;
  }
  
 loopend:

  umsg->rects = htons(n);
	
  if(y == vs->y + vs->h && x == vs->x + vs->w) {
    vs->x2 = vs->y2 = 0;
  }

  if(n > 0) {
    /*    printf("Sending %d rects, %d bytes (%p, %p, %p)\n", n, len,
	  uip_appdata, umsg, ptr);*/
    uip_send(uip_appdata, len);
  }

}
/*-----------------------------------------------------------------------------------*/
#define NUMKEYS 20
static char keys[NUMKEYS];
static int firstkey, lastkey;


char
vnc_out_keyavail(void)
{
  return firstkey != lastkey;
}

char
vnc_out_getkey(void)
{
  char key;
  key = keys[firstkey];
  
  if(firstkey != lastkey) {
    ++firstkey;
    if(firstkey >= NUMKEYS) {
      firstkey = 0;
    }
  }
  
  return key;  
}

void
vnc_out_key_event(struct vnc_server_state *vs)
{
  register struct rfb_key_event *ev;
  
  ev = (struct rfb_key_event *)uip_appdata;

  if(ev->down != 0) {
    if(vs->sendmsg == SEND_NONE) {
      vs->sendmsg = SEND_UPDATE;
    }


    if(ev->key[2] == 0 ||
       (ev->key[2] == 0xff &&	
	(ev->key[3] == CH_HOME ||
	 ev->key[3] == CH_TAB ||
	 ev->key[3] == CH_ESC ||
	 ev->key[3] == CH_DEL ||
	 ev->key[3] == CH_ENTER ||
	 ev->key[3] == CH_CURS_LEFT ||
	 ev->key[3] == CH_CURS_UP ||
	 ev->key[3] == CH_CURS_RIGHT ||
	 ev->key[3] == CH_CURS_DOWN))) {
      
      keys[lastkey] = ev->key[3];
      ++lastkey;
      if(lastkey >= NUMKEYS) {
	lastkey = 0;
      }
    }
  }

  check_updates(vs);
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_pointer_event(struct vnc_server_state *vs)
{
  struct rfb_pointer_event *ev;
  u16_t evx, evy;
  
  ev = (struct rfb_pointer_event *)uip_appdata;

  evx = htons(ev->x);
  evy = htons(ev->y);
  
  if(evx > SCREEN_X && evx < SCREEN_WIDTH - 2 * SCREEN_X &&
     evy > SCREEN_Y && evy < SCREEN_HEIGHT - 2 * SCREEN_Y) {

    mouse_button = ev->buttonmask & RFB_BUTTON_MASK1;
    
    mouse_x = evx - SCREEN_X;
    mouse_y = evy - SCREEN_Y;

    check_updates(vs);    
  }    
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_acked(register struct vnc_server_state *vs)
{
  if(vs->state != VNC_RUNNING) {
    return;
  }
  if(vs->sendmsg == SENT_BLANK) {
    init_send_screen(vs);
  } else if(vs->sendmsg == SEND_BLANK) {
    /* Do nothing until sendmsg == SENT_BLANK. */
  } else if(vs->sendmsg == SEND_SCREEN) {
    /* When the screen has been fully drawn, ->x2 and ->y2 are both
       set to 0 to indicate this.*/
    if(vs->x2 == 0 && vs->y2 == 0) {
      vs->sendmsg = SEND_NONE;
      
      /* If there was an updaterequest for the entire screen, we can
	 clear that flag now. */
      if(vs->updates_current != NULL) {	
	vnc_server_update_free(vs, vs->updates_current);
	vs->updates_current = NULL;
      }
      check_updates(vs);
    } else {
      vs->x1 = vs->x2;
      vs->y1 = vs->y2;
    }
	      
  } else if(vs->sendmsg == SEND_UPDATE) {
    if(vs->x2 == 0 && vs->y2 == 0) {
      /* So, we have updated the area that we needed. We now check if
	 there have been any recent full screen update requests. If
	 so, we need to go to the SEND_SCREEN state. Else, we see if
	 there were more areas that needed to be updated and if so,
	 we'll continue with those. */

      vs->sendmsg = SEND_NONE;

      if(vs->updates_current != NULL) {
	vnc_server_update_free(vs, vs->updates_current);
	vs->updates_current = NULL;

      }
      check_updates(vs);
#if 0
      if(vs->updaterequest == VNC_SERVER_UPDATE_FULL) {
	check_updates(vs);
      } else {
	vs->updatesptr2 = (vs->updatesptr2 + 1) %
	  VNC_SERVER_MAX_UPDATES;

	/* If there are no more updates to do, we'll go back to the
	   SEND_NONE state. */	
	if(vs->updatesptr2 == vs->updatesptr) {
	  vs->updatetype = VNC_SERVER_UPDATE_NONE;
	} else {	 
	  /* Otherwise, we continue to update the next area. */
	  vs->updaterequest = VNC_SERVER_UPDATE_PARTS;
	  check_updates(vs);
	}
      }
#endif /* 0 */
    } else {	     
      vs->x1 = vs->x2;
      vs->y1 = vs->y2;
    }    
  } else {
    vs->sendmsg = SEND_NONE;
  }
}
/*-----------------------------------------------------------------------------------*/
void
vnc_out_poll(struct vnc_server_state *vs)
{
  /*  PRINTF(("vs->state %d, sendmsg %d, updatetype %d, updatereq %d\n",
      vs->state, vs->sendmsg, vs->updatetype, vs->updaterequest);*/
  
  if(vs->state == VNC_RUNNING &&
     vs->sendmsg == SEND_NONE) {
    check_updates(vs);
    vnc_server_send_data(vs);
  }
}
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_MOUSE_SUPPORT
void
ctk_mouse_init(void)
{

}
/*-----------------------------------------------------------------------------------*/
unsigned short
ctk_mouse_x(void)
{
  return mouse_x;
}
/*-----------------------------------------------------------------------------------*/
unsigned short
ctk_mouse_y(void)
{
  return mouse_y;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
ctk_mouse_button(void)
{
  return mouse_button;
}
/*-----------------------------------------------------------------------------------*/
void
ctk_mouse_hide(void)
{
}
/*-----------------------------------------------------------------------------------*/
void
ctk_mouse_show(void)
{
}
/*-----------------------------------------------------------------------------------*/
#endif /* CTK_CONF_MOUSE_SUPPORT */
