Beispiel #1
0
static FAR void *vnc_updater(FAR void *arg)
{
  FAR struct vnc_session_s *session = (FAR struct vnc_session_s *)arg;
  FAR struct vnc_fbupdate_s *srcrect;
  int ret;

  DEBUGASSERT(session != NULL);
  gvdbg("Updater running for Display %d\n", session->display);

  /* Loop, processing updates until we are asked to stop.
   * REVISIT: Probably need some kind of signal mechanism to wake up
   * vnc_remove_queue() in order to stop.  Or perhaps a special STOP
   * message in the queue?
   */

  while (session->state == VNCSERVER_RUNNING)
    {
      /* Get the next queued rectangle update.  This call will block until an
       * upate is available for the case where the update queue is empty.
       */

      srcrect = vnc_remove_queue(session);
      DEBUGASSERT(srcrect != NULL);

      updvdbg("Dequeued {(%d, %d),(%d, %d)}\n",
              srcrect->rect.pt1.x, srcrect->rect.pt1.y,
              srcrect->rect.pt2.x, srcrect->rect.pt2.y);

      /* Attempt to use RRE encoding */

      ret = vnc_rre(session, &srcrect->rect);
      if (ret == 0)
        {
          /* Perform the framebuffer update using the default RAW encoding */

          ret = vnc_raw(session, &srcrect->rect);
        }

      /* Release the update structure */

      vnc_free_update(session, srcrect);

      /* Break out and terminate the server if the encoding failed */

      if (ret < 0)
        {
          gdbg("ERROR: Encoding failed: %d\n", ret);
          break;
        }
    }

  session->state = VNCSERVER_STOPPED;
  return NULL;
}
Beispiel #2
0
static int
vnc_inflate(struct connection *cx)
{
	struct zlib *zlib = cx->encoding_def[zlib_encoding].priv;

	int length;
	int res;
	int flush;
	const uint32_t max_length = 0x100000;
	int chunked;
	struct buffer input;

	debug(3, "zlib_inflate\n");

	chunked = zlib->length > max_length;
	length = chunked ? max_length : zlib->length;

	if (cx->input.wpos < cx->input.rpos + length) {
		length = cx->input.wpos - cx->input.rpos;
		chunked = 0;
		flush = Z_NO_FLUSH;
	}
	else
		flush = chunked ? Z_NO_FLUSH : Z_SYNC_FLUSH;

	zlib->zstr.avail_in = length;
	zlib->zstr.next_in = &cx->input.data[cx->input.rpos];

	do {
		if (cx->work.wpos == cx->work.size) {
			if (buffer_reserve(&cx->work,
				cx->work.size + 65536))
			{
				debug(1, "zlib realloc failed\n");
				return close_connection(cx, -1);
			}
		}
		zlib->zstr.avail_out = cx->work.size - cx->work.wpos;
		zlib->zstr.next_out = &cx->work.data[cx->work.wpos];

		res = inflate(&zlib->zstr, flush);
		switch (res) {
		case Z_NEED_DICT:
		case Z_DATA_ERROR:
		case Z_MEM_ERROR:
			debug(1, "zlib inflate error %d\n", res);
			inflateEnd(&zlib->zstr);
			return close_connection(cx, -1);
		}

		cx->work.wpos = cx->work.size - zlib->zstr.avail_out;
	} while (!zlib->zstr.avail_out);

	zlib->length -= length - zlib->zstr.avail_in;
	cx->input.rpos += length - zlib->zstr.avail_in;

	if (zlib->length) {
		cx->action = vnc_inflate;
		return chunked;
	}

	input = cx->input;
	cx->input = cx->work;
	res = vnc_raw(cx);
	cx->input = input;
	if (!res)
		return close_connection(cx, -1);

	cx->work.rpos = 0;
	cx->work.wpos = 0;

	return 1;
}