Ejemplo n.º 1
0
static void rf_client_ptrevent(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  CARD16 x, y;
  CARD8 msg[6];

  if (!cl->readonly) {
    msg[0] = 5;                 /* PointerEvent */
    msg[1] = cur_slot->readbuf[0];
    x = buf_get_CARD16(&cur_slot->readbuf[1]);
    y = buf_get_CARD16(&cur_slot->readbuf[3]);

    /* Pointer position should fit in the host screen */
    if (x >= g_screen_info.width)
      x = g_screen_info.width - 1;
    if (y >= g_screen_info.height)
      y = g_screen_info.height - 1;

    buf_put_CARD16(&msg[2], x);
    buf_put_CARD16(&msg[4], y);
    pass_msg_to_host(msg, sizeof(msg));
  }

  aio_setread(rf_client_msg, NULL, 1);
}
Ejemplo n.º 2
0
void buf_put_pixfmt(void *buf, RFB_PIXEL_FORMAT *format)
{
  CARD8 *bbuf = buf;

  memcpy(buf, format, SZ_RFB_PIXEL_FORMAT);
  buf_put_CARD16(&bbuf[4], format->r_max);
  buf_put_CARD16(&bbuf[6], format->g_max);
  buf_put_CARD16(&bbuf[8], format->b_max);
}
Ejemplo n.º 3
0
int put_rect_header(CARD8 *buf, FB_RECT *r)
{

  buf_put_CARD16(buf, r->x);
  buf_put_CARD16(&buf[2], r->y);
  buf_put_CARD16(&buf[4], r->w);
  buf_put_CARD16(&buf[6], r->h);
  buf_put_CARD32(&buf[8], r->enc);

  return 12;                    /* 12 bytes written */
}
Ejemplo n.º 4
0
AIO_BLOCK *rfb_encode_copyrect_block(CL_SLOT *cl, FB_RECT *r)
{
  AIO_BLOCK *block;

  block = malloc(sizeof(AIO_BLOCK) + 12 + 4);
  if (block) {
    put_rect_header(block->data, r);
    buf_put_CARD16(&block->data[12], r->src_x);
    buf_put_CARD16(&block->data[14], r->src_y);
    block->data_size = 12 + 4;
  }

  return block;
}
Ejemplo n.º 5
0
static void send_new_cliprects(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  FB_RECT rect;

  crDebug("Sending new cliprects to proxy: %d, %d .. %d, %d",
          cl->new_clip_bounds.x1,
          cl->new_clip_bounds.y1,
          cl->new_clip_bounds.x2,
          cl->new_clip_bounds.y2);

  log_write(LL_DEBUG, "Sending NewCliprects (%dx%d) to %s",
            (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);

  buf_put_CARD16(&msg_hdr[2], 1); /* one rect */
  aio_write(NULL, msg_hdr, 4);

  rect.x = cl->new_clip_bounds.x1;
  rect.y = cl->new_clip_bounds.y1;
  rect.w = cl->new_clip_bounds.x2 - cl->new_clip_bounds.x1;
  rect.h = cl->new_clip_bounds.y2 - cl->new_clip_bounds.y1;
  rect.enc = RFB_ENCODING_CLIPRECTS;

  put_rect_header(rect_hdr, &rect);
  aio_write(wf_client_update_finished, rect_hdr, 12);

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;
}
Ejemplo n.º 6
0
static void send_newfbsize(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  FB_RECT rect;

  log_write(LL_DEBUG, "Sending NewFBSize update (%dx%d) to %s",
            (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);

  buf_put_CARD16(&msg_hdr[2], 1);
  aio_write(NULL, msg_hdr, 4);

  rect.x = 0;
  rect.y = 0;
  rect.w = cl->fb_width;
  rect.h = cl->fb_height;
  rect.enc = RFB_ENCODING_NEWFBSIZE;

  put_rect_header(rect_hdr, &rect);
  aio_write(wf_client_update_finished, rect_hdr, 12);

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;
}
Ejemplo n.º 7
0
static void request_update(int incr)
{
  HOST_SLOT *hs = (HOST_SLOT *)cur_slot;
  unsigned char fbupdatereq_msg[] = {
    3,                          /* Message id */
    0,                          /* Incremental if 1 */
    0, 0, 0, 0,                 /* X position, Y position */
    0, 0, 0, 0                  /* Width, height */
  };

  fbupdatereq_msg[1] = (incr) ? 1 : 0;
  buf_put_CARD16(&fbupdatereq_msg[6], hs->fb_width);
  buf_put_CARD16(&fbupdatereq_msg[8], hs->fb_height);

  log_write(LL_DEBUG, "Sending FramebufferUpdateRequest message");
  aio_write(NULL, fbupdatereq_msg, sizeof(fbupdatereq_msg));
}
Ejemplo n.º 8
0
static void rf_client_initmsg(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  unsigned char msg_server_init[24];

  if (cur_slot->readbuf[0] == 0) {
    log_write(LL_WARN, "Non-shared session requested by %s", cur_slot->name);
    aio_close(0);
  }

  /* Save initial desktop geometry for this client */
  cl->fb_width = g_screen_info.width;
  cl->fb_height = g_screen_info.height;
  cl->enable_newfbsize = 0;
  cl->enable_cliprects_enc = 0;

  /* Send ServerInitialisation message */
  buf_put_CARD16(msg_server_init, cl->fb_width);
  buf_put_CARD16(msg_server_init + 2, cl->fb_height);
  buf_put_pixfmt(msg_server_init + 4, &g_screen_info.pixformat);
  buf_put_CARD32(msg_server_init + 20, g_screen_info.name_length);
  aio_write(NULL, msg_server_init, 24);
  aio_write(NULL, g_screen_info.name, g_screen_info.name_length);
  aio_setread(rf_client_msg, NULL, 1);

  /* Set up initial pixel format and encoders' parameters */
  memcpy(&cl->format, &g_screen_info.pixformat, sizeof(RFB_PIXEL_FORMAT));
  cl->trans_func = transfunc_null;
  cl->bgr233_f = 0;
  cl->compress_level = 6;       /* default compression level */
  cl->jpeg_quality = -1;        /* disable JPEG by default */

  /* The client did not request framebuffer updates yet */
  cl->update_requested = 0;
  cl->update_in_progress = 0;
  REGION_INIT(&cl->pending_region, NullBox, 16);
  REGION_INIT(&cl->copy_region, NullBox, 8);
  cl->newfbsize_pending = 0;
  cl->new_cliprects = 0;

  /* We are connected. */
  cl->connected = 1;
}
Ejemplo n.º 9
0
	void ScreenEncoder::sendUpdate(OutputStream& out)
	{

		ScopedLock s(rectLock);
		sendCount++;
		CL_SLOT *cl = &slot;
//		BoxRec fb_rect;
//		RegionRec fb_region, clip_region, outer_region;
		CARD8 msg_hdr[4] =
		{
			0, 0, 0, 1
		};
		CARD8 rect_hdr[12];
		ScreenRectangle rect;
	
	
		int num_penging_rects = pendingRectList.size();
		
		//if(num_penging_rects == 0){ return; }
		buf_put_CARD16(&msg_hdr[2], 0xFFFF);
		if(num_penging_rects > 0) 
		{
			out.write(msg_hdr, 4);
		}
		else 
		{
			return;
		}
	
		//DDSS_VERBOSE("ScreenShareApp")<<"(sub) Pending Rects : "<<pendingRects.size()<<std::endl;
		/* For each of the usual pending rectangles: */
		while(pendingRectList.size() > 0)
		{

			
			ScreenRectangle rect = pendingRectList[0]; 
			pendingRectList.erase(pendingRectList.begin());
			if(rect.enc == RFB_ENCODING_COPYRECT)
			{
				DDSS_VERBOSE("ScreenShareApp")<<"CopyRect : "<<rect<<std::endl;
				CARD8 tmp[16];
				RFBHelper::put_rect_copy(tmp,&rect);
				out.write(tmp,16);
			}
			else if(rect.enc == RFB_ENCODING_CURSOR_POSITION)
			{
				CARD8 tmp[12];
				RFBHelper::put_rect_header(tmp,&rect);
				out.write(tmp,12);
				DDSS_VERBOSE("Enc")<<"Sending Cursor update "<<rect<<" to sub!!!"<<std::endl;
			}
			else if(rect.enc == RFB_ENCODING_TIGHT)// || rect.enc == RFB_ENCODING_COPYRECT)
			{
				rect.enc = RFB_ENCODING_TIGHT;
				if(tightEncoder)
				{
					ByteBufferOutputStream& bos = (ByteBufferOutputStream&)out;
					size_t l1 = bos.get()->getLength();
					tightEncoder->encode(out, &rect);
					size_t l2 = bos.get()->getLength();

					
					DDSS_VERBOSE("[SUB-ENC]")<<"("<< (l2-l1)<<" bytes  / "<<(rect.w * rect.h * 3)<<" bytes)"<<rect<<std::endl;
				}
			}
			else if(rect.enc == RFB_ENCODING_NEWFBSIZE)
			{
				CARD8 tmp[12];
				RFBHelper::put_rect_header(tmp,&rect);
				out.write(tmp,12);
			}
			else
			{
				//DDSS_VERBOSE("ScreenShareApp")<<"[SUB-ENC] UNKNOWN ENCODED RECT : "<<rect<<std::endl;
			}
			
			
			size_t len = ((ByteBufferOutputStream&)out).get()->getLength();
			if(len >= maxSize)
			{
				break;
			}
		}
		size_t len = ((ByteBufferOutputStream&)out).get()->getLength();
		if(len > maxSize)
		{
			overflowCount++;
		}
		else
		{
			underflowCount++;
		}

		/* Send LastRect marker. */
		if(num_penging_rects > 0)
		{
			rect.x = rect.y = rect.w = rect.h = 0;
			rect.enc = RFB_ENCODING_LASTRECT;
			RFBHelper::put_rect_header(rect_hdr, &rect);
			out.write(rect_hdr, 12);
		}
	
	}
Ejemplo n.º 10
0
static void send_update(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  BoxRec fb_rect;
  RegionRec fb_region, clip_region, outer_region;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  int num_copy_rects, num_pending_rects, num_all_rects;
  int raw_bytes = 0, hextile_bytes = 0;
  int i, idx, rev_order;
  static int counter = 0;

#ifdef NETLOGGER
  aio_set_serial_number(&cl->s, cl->serial_number);
#endif

  counter++;
  vncspuLog(1, "Begin send update %d", counter);

  CRASSERT(vnc_spu.serverBuffer);

  /*crDebug("Enter send_update to %s", cur_slot->name);*/

  /* check if clipping has changed since we got the pixels and update
   * the pending region if needed.
   */
  if (NewClip) {
     /*crDebug("Getting updated cliprects");*/
     vncspuGetScreenRects(&cl->pending_region);
     num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
     /*crDebug("Now, %d rects", num_pending_rects);*/
     if (num_pending_rects == 0 && cl->enable_frame_sync) {
        /* always need to send _something_ for framesync to work */
        BoxRec b;
        b.x1 = 0;
        b.y1 = 0;
        b.x2 = 1;
        b.y2 = 1;
        REGION_UNINIT(&cl->pending_region);
        REGION_INIT(&cl->pending_region, &b, 1);
     }
     NewClip = 0;
  }
  /*PrintRegion("Sending", &cl->pending_region);*/


  /* Process framebuffer size change. */
  if (cl->newfbsize_pending) {
    /* Update framebuffer size, clear newfbsize_pending flag. */
    cl->fb_width = g_screen_info.width;
    cl->fb_height = g_screen_info.height;
    cl->newfbsize_pending = 0;
    log_write(LL_DEBUG, "Applying new framebuffer size (%dx%d) to %s",
              (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);
    /* In any case, mark all the framebuffer contents as changed. */
    fb_rect.x1 = 0;
    fb_rect.y1 = 0;
    fb_rect.x2 = cl->fb_width;
    fb_rect.y2 = cl->fb_height;
    REGION_INIT(&fb_region, &fb_rect, 1);
    REGION_COPY(&cl->pending_region, &fb_region);
    REGION_UNINIT(&fb_region);
    REGION_EMPTY(&cl->copy_region);
    /* If NewFBSize is supported by the client, send only NewFBSize
       pseudo-rectangle, pixel data will be sent in the next update. */
    if (cl->enable_newfbsize) {
      send_newfbsize();
      vncspuUnlockFrameBuffer();
      return;
    }
  } else {
    /* Exclude CopyRect areas covered by pending_region. */
    REGION_SUBTRACT(&cl->copy_region, &cl->copy_region, &cl->pending_region);
  }

#if 00
  if (cl->enable_cliprects_enc && cl->new_cliprects) {
    send_new_cliprects();
    vncspuUnlockFrameBuffer();
    cl->new_cliprects = 0;
    return;
  }
#endif

  /* Clip regions to the rectangle requested by the client. */
  REGION_INIT(&clip_region, &cl->update_rect, 1);

  REGION_INTERSECT(&cl->pending_region, &cl->pending_region, &clip_region);
  if (REGION_NOTEMPTY(&cl->copy_region)) {
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);

    REGION_INIT(&outer_region, NullBox, 8);
    REGION_COPY(&outer_region, &cl->copy_region);
    REGION_TRANSLATE(&clip_region, cl->copy_dx, cl->copy_dy);
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);
    REGION_SUBTRACT(&outer_region, &outer_region, &cl->copy_region);
    REGION_UNION(&cl->pending_region, &cl->pending_region, &outer_region);
    REGION_UNINIT(&outer_region);
  }
  REGION_UNINIT(&clip_region);

  /* Reduce the number of rectangles if possible. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    region_pack(&cl->pending_region, 32);
  } else {
    region_pack(&cl->pending_region, 12);
  }

  /* Compute the number of rectangles in regions. */
  num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
  num_copy_rects = REGION_NUM_RECTS(&cl->copy_region);
  num_all_rects = num_pending_rects + num_copy_rects;
  if (num_all_rects == 0) {
    vncspuUnlockFrameBuffer();
    return;
  }

  log_write(LL_DEBUG, "Sending framebuffer update (min %d rects) to %s",
            num_all_rects, cur_slot->name);

  /* Prepare and send FramebufferUpdate message header. */
  /* FIXME: Enable Tight encoding even if LastRect is not supported. */
  /* FIXME: Do not send LastRect if all the rectangles are CopyRect. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    buf_put_CARD16(&msg_hdr[2], 0xFFFF);
  } else {
    buf_put_CARD16(&msg_hdr[2], num_all_rects);
  }
  aio_write(NULL, msg_hdr, 4);

  /* Determine the order in which CopyRect rectangles should be sent. */
  rev_order = (cl->copy_dy > 0 || (cl->copy_dy == 0 && cl->copy_dx > 0));

  /* For each CopyRect rectangle: */
  for (i = 0; i < num_copy_rects; i++) {
    FB_RECT rect;
    AIO_BLOCK *block;
    idx = (rev_order) ? num_copy_rects - i - 1 : i;
    rect.x = REGION_RECTS(&cl->copy_region)[idx].x1;
    rect.y = REGION_RECTS(&cl->copy_region)[idx].y1;
    rect.w = REGION_RECTS(&cl->copy_region)[idx].x2 - rect.x;
    rect.h = REGION_RECTS(&cl->copy_region)[idx].y2 - rect.y;
    rect.src_x = rect.x - cl->copy_dx;
    rect.src_y = rect.y - cl->copy_dy;
    rect.enc = RFB_ENCODING_COPYRECT;
    log_write(LL_DEBUG, "Sending CopyRect rectangle %dx%d at %d,%d to %s",
              (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
              cur_slot->name);

    /* Prepare the CopyRect rectangle. */
    block = rfb_encode_copyrect_block(cl, &rect);

    /* Send the rectangle.
       FIXME: Check for block == NULL? */
    aio_write_nocopy(NULL, block);
  }

  if (cl->enc_prefer == RFB_ENCODING_TIGHT) {
    /* needed for successful caching of zlib-compressed data (tight) */
    rfb_reset_tight_encoder(cl);
  }

  if (num_pending_rects) {
    /* Lock around fb access so other thread doesn't change contents while
     * we're encoding.
     */
#ifdef NETLOGGER
    if (vnc_spu.netlogger_url) {
      NL_info("vncspu", "spu.encode.begin",
              "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
    }
#endif

    /* For each of the usual pending rectangles: */
    for (i = 0; i < num_pending_rects; i++) {
      FB_RECT rect;
      AIO_BLOCK *block;
			/*
      crDebug("sending rect %d of %d: %d, %d .. %d, %d", i, num_pending_rects,
              REGION_RECTS(&cl->pending_region)[i].x1,
              REGION_RECTS(&cl->pending_region)[i].y1,
              REGION_RECTS(&cl->pending_region)[i].x2,
              REGION_RECTS(&cl->pending_region)[i].y2);
			*/
      rect.x = REGION_RECTS(&cl->pending_region)[i].x1;
      rect.y = REGION_RECTS(&cl->pending_region)[i].y1;
      rect.w = REGION_RECTS(&cl->pending_region)[i].x2 - rect.x;
      rect.h = REGION_RECTS(&cl->pending_region)[i].y2 - rect.y;
      log_write(LL_DEBUG, "Sending rectangle %dx%d at %d,%d to %s enc 0x%x",
                (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
                cur_slot->name, cl->enc_prefer);

      if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
        /* Use Tight encoding */
        rect.enc = RFB_ENCODING_TIGHT;
        /* lock to prevent glReadPixels in other thread changing data */
        rfb_encode_tight(cl, &rect);
        continue;                 /* Important! */
      } else if (cl->enc_prefer == RFB_ENCODING_RAW24) {
        rect.enc = RFB_ENCODING_RAW24;
        block = rfb_encode_raw24_block(cl, &rect);
      } else if ( cl->enc_prefer != RFB_ENCODING_RAW &&
                  cl->enc_enable[RFB_ENCODING_HEXTILE] ) {
        /* Use Hextile encoding */
        rect.enc = RFB_ENCODING_HEXTILE;
        block = rfb_encode_hextile_block(cl, &rect);
        if (block != NULL) {
          hextile_bytes += block->data_size;
          raw_bytes += rect.w * rect.h * (cl->format.bits_pixel / 8);
        }
      } else {
        /* Use Raw encoding */
        rect.enc = RFB_ENCODING_RAW;
        if (vnc_spu.half_rez) {
           block = rfb_encode_raw_block_halfrez(cl, &rect);
        }
        else {
           block = rfb_encode_raw_block(cl, &rect);
        }
      }

      /* Send the rectangle.
         FIXME: Check for block == NULL? */
      aio_write_nocopy(NULL, block);
    }

  } /* if num_pending_rects */


  REGION_EMPTY(&cl->pending_region);
  REGION_EMPTY(&cl->copy_region);

  /* Send LastRect marker. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    FB_RECT rect;
    rect.x = rect.y = rect.w = rect.h = 0;
    rect.enc = RFB_ENCODING_LASTRECT;
    put_rect_header(rect_hdr, &rect);
    aio_write(NULL, rect_hdr, 12);
  }

  /* Set the last block's callback function */
  /* All prev blocks had NULL callbacks */
  assert(cur_slot->outqueue_last);
  if (cur_slot->outqueue_last) {
    cur_slot->outqueue_last->func = wf_client_update_finished;
  }

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;

#ifdef NETLOGGER
  if (vnc_spu.netlogger_url) {
    NL_info("vncspu", "spu.encode.end",
            "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
  }
  aio_set_serial_number(&cl->s, 0);
#endif

  vncspuUnlockFrameBuffer(); /* encoder done with buffer */

  /*crDebug("Leave send_update");*/

  vncspuLog(1, "End send update %d", counter);
}