/*-----------------------------------------------------------------------------------*/
static void
update_area(u8_t x, u8_t y, u8_t w, u8_t h)
{
  u8_t i;
  
  if(h == 0 || w == 0) {
    return;
  }
  
  /* Update for all active VNC connections. */
  for(i = 0; i < CTK_VNCSERVER_CONF_NUMCONNS; ++i) {
    if(conns[i].state != VNC_DEALLOCATED) {
      vnc_out_update_area(&conns[i],
			  x, y, w, h);
    }
  }

}
/*-----------------------------------------------------------------------------------*/
static uint8_t
vnc_read_data(CC_REGISTER_ARG struct vnc_server_state *vs)
{
    uint8_t *appdata;
    uint16_t len;
    struct rfb_fb_update_request *req;
    /*  uint8_t niter;*/

    len = uip_datalen();
    appdata = (uint8_t *)uip_appdata;

    /* First, check if there is data left to discard since last read. */
    if(vs->readlen > 0) {
        appdata += vs->readlen;
        if(len > vs->readlen) {
            len -= vs->readlen;
            vs->readlen = 0;
        } else {
            vs->readlen -= len;
            len = 0;
        }
    }

    if(vs->readlen != 0) {
        return 1;
    }

    /* All data read and ignored, parse next message. */
    /*  for(niter = 32; niter > 0 && len > 0; --niter) {*/
    while(len > 0) {
        switch(vs->state) {
        case VNC_VERSION:
        case VNC_VERSION2:
            PRINTF(("Read in version\n"));
            /* Receive and ignore client version string (12 bytes). */
            vs->state = VNC_AUTH;
            vs->readlen = 12;
            break;

        case VNC_AUTH:
        case VNC_AUTH2:
            PRINTF(("Read in auth \n"));
            /* Read and discard initialization from client (1 byte). */
            vs->readlen = 1;
            vs->state = VNC_INIT;
            break;

        case VNC_INIT:
        case VNC_INIT2:
            PRINTF(("Read in init \n"));
            vs->readlen = 0;
            vs->state = VNC_RUNNING;

        case VNC_RUNNING:
            /* Handle all client events. */
            switch(*appdata) {
            case RFB_SET_PIXEL_FORMAT:
                PRINTF(("Set pixel format\n"));
                vs->readlen = sizeof(struct rfb_set_pixel_format);
                /* Check if client runs with BGR233 format. If not, abort the
                   connection. */
                /* XXX: not implemented yet. */
                break;

            case RFB_FIX_COLORMAP_ENTRIES:
                PRINTF(("Fix colormap entries\n"));
                return 0;

            case RFB_SET_ENCODINGS:
                PRINTF(("Set encodings\n"));
                vs->readlen = sizeof(struct rfb_set_encoding);
                vs->readlen += uip_htons(((struct rfb_set_encoding *)appdata)->encodings) * 4;
                /* Make sure that client supports the encodings we use. */
                /* XXX: not implemented yet. */
                break;

            case RFB_FB_UPDATE_REQ:
                PRINTF(("Update request\n"));
                vs->update_requested = 1;
                vs->readlen = sizeof(struct rfb_fb_update_request);
                /* blank the screen initially */
                req = (struct rfb_fb_update_request *)appdata;
                if(req->incremental == 0) {
                    /*	  vs->sendmsg = SEND_BLANK;*/
                    vnc_out_update_area(vs, 0, 0, vs->w, vs->h);
                }
                break;

            case RFB_KEY_EVENT:
                vs->readlen = sizeof(struct rfb_key_event);
                vnc_key_event(vs);
                break;

            case RFB_POINTER_EVENT:
                vs->readlen = sizeof(struct rfb_pointer_event);
                vnc_pointer_event(vs);
                break;

            case RFB_CLIENT_CUT_TEXT:
                PRINTF(("Client cut text\n"));

                if(((struct rfb_client_cut_text *)appdata)->len[0] != 0 ||
                        ((struct rfb_client_cut_text *)appdata)->len[1] != 0) {
                    return 0;

                }
                vs->readlen = sizeof(struct rfb_client_cut_text) +
                              (((struct rfb_client_cut_text *)appdata)->len[2] << 8) +
                              ((struct rfb_client_cut_text *)appdata)->len[3];
                /*	return 0;*/
                break;

            default:
                PRINTF(("Unknown message %d\n", *appdata));
                return 0;
            }
            break;

        default:
            return 0;
        }

        if(vs->readlen > 0) {
            if(len > vs->readlen) {
                len -= vs->readlen;
                appdata += vs->readlen;
                vs->readlen = 0;
            } else {
                vs->readlen -= len;
                len = 0;
            }
        } else {
            /* Lost data. */
            break;
        }

    }

    /*  if(vs->readlen > 0) {
      printf("More data %d\n", vs->readlen);
      }*/

    /*  uip_appdata = appdata;*/

    return 1;
}