/* FIXME: Not as efficient as it could be. */
static void rf_host_hextile_subrects(void)
{
  CARD8 *ptr;
  CARD8 pos, dim;
  int i;

  ptr = cur_slot->readbuf;

  if (s_subenc & RFB_HEXTILE_SUBRECTS_COLOURED) {
    fbs_spool_data(ptr, s_num_subrects * 6);
    for (i = 0; i < (int)s_num_subrects; i++) {
      memcpy(&s_fg, ptr, sizeof(s_fg));
      ptr += sizeof(s_fg);
      pos = *ptr++;
      dim = *ptr++;
      hextile_fill_subrect(pos, dim);
    }
  } else {
    fbs_spool_data(ptr, s_num_subrects * 2);
    for (i = 0; i < (int)s_num_subrects; i++) {
      pos = *ptr++;
      dim = *ptr++;
      hextile_fill_subrect(pos, dim);
    }
  }

  hextile_next_tile();
}
static void rf_host_hextile_hex(void)
{
  CARD32 *from_ptr = hextile_buf;
  int data_size;

  /* Get background and foreground colors */
  if (s_subenc & RFB_HEXTILE_BG_SPECIFIED) {
    s_bg = *from_ptr++;
    fill_fb_rect(&s_tile, s_bg);
  }
  if (s_subenc & RFB_HEXTILE_FG_SPECIFIED) {
    s_fg = *from_ptr++;
  }

  if (s_subenc & RFB_HEXTILE_ANY_SUBRECTS) {
    fbs_spool_data(hextile_buf, (from_ptr - hextile_buf) * sizeof(CARD32) + 1);
    s_num_subrects = *((CARD8 *)from_ptr);
    if (s_subenc & RFB_HEXTILE_SUBRECTS_COLOURED) {
      data_size = 6 * (unsigned int)s_num_subrects;
    } else {
      data_size = 2 * (unsigned int)s_num_subrects;
    }
    if (data_size > 0) {
      aio_setread(rf_host_hextile_subrects, NULL, data_size);
      return;
    }
  } else {
    fbs_spool_data(hextile_buf, (from_ptr - hextile_buf) * sizeof(CARD32));
  }

  hextile_next_tile();
}
Example #3
0
/**
 * Called when we get a rfbFramebufferUpdate message.
 */
static void rf_host_fbupdate_hdr(void)
{
  CARD8 hdr_buf[4];

  rect_count = buf_get_CARD16(&cur_slot->readbuf[1]);

  if (rect_count == 0xFFFF) {
    log_write(LL_DETAIL, "Receiving framebuffer update");
  } else {
    log_write(LL_DETAIL, "Receiving framebuffer update, %d rectangle(s)",
              rect_count);
  }

  hdr_buf[0] = 0;
  memcpy(&hdr_buf[1], cur_slot->readbuf, 3);
  fbs_spool_data(hdr_buf, 4);

  if (rect_count) {
    aio_setread(rf_host_fbupdate_recthdr, NULL, 12);
  } else {
    log_write(LL_DEBUG, "Requesting incremental framebuffer update");
    request_update(1);
    aio_setread(rf_host_msg, NULL, 1);
  }
}
Example #4
0
static void rf_host_copyrect(void)
{
  CARD32 *src_ptr;
  CARD32 *dst_ptr;
  int width/* = (int)g_fb_width*/;
  int row;
#ifdef CHROMIUM
  CARD32 *g_framebuffer;
  CARD16 g_fb_width, g_fb_height;
  g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height);
  width = g_fb_width;
#endif

  fbs_spool_data(cur_slot->readbuf, 4);

  cur_rect.src_x = buf_get_CARD16(cur_slot->readbuf);
  cur_rect.src_y = buf_get_CARD16(&cur_slot->readbuf[2]);

  if ( cur_rect.src_x >= g_fb_width ||
       cur_rect.src_x + cur_rect.w > g_fb_width ||
       cur_rect.src_y >= g_fb_height ||
       cur_rect.src_y + cur_rect.h > g_fb_height ) {
    log_write(LL_ERROR,
              "CopyRect from outside of the framebuffer: %dx%d from %d,%d",
              (int)cur_rect.w, (int)cur_rect.h,
              (int)cur_rect.src_x, (int)cur_rect.src_y);
    aio_close(0);
    return;
  }

  if (cur_rect.src_y > cur_rect.y) {
    /* Copy rows starting from top */
    src_ptr = &g_framebuffer[cur_rect.src_y * width + cur_rect.src_x];
    dst_ptr = &g_framebuffer[cur_rect.y * width + cur_rect.x];
    for (row = 0; row < cur_rect.h; row++) {
      memmove(dst_ptr, src_ptr, cur_rect.w * sizeof(CARD32));
      src_ptr += width;
      dst_ptr += width;
    }
  } else {
    /* Copy rows starting from bottom */
    src_ptr = &g_framebuffer[(cur_rect.src_y + cur_rect.h - 1) * width +
                             cur_rect.src_x];
    dst_ptr = &g_framebuffer[(cur_rect.y + cur_rect.h - 1) * width +
                             cur_rect.x];
    for (row = 0; row < cur_rect.h; row++) {
      memmove(dst_ptr, src_ptr, cur_rect.w * sizeof(CARD32));
      src_ptr -= width;
      dst_ptr -= width;
    }
  }

  fbupdate_rect_done();
}
Example #5
0
static void rf_host_richcursor_bmps(void)
{
  fbs_spool_data(cur_slot->readbuf, s_read_size);
  s_curs_rect = s_new_curs_rect;
  s_bmps = realloc(s_bmps, s_read_size);
  if (!s_bmps) {
    log_write(LL_ERROR, "Failed to allocate memory for cursor pixmaps");
    aio_close(0);
    return;
  }
  memcpy(s_bmps, s_new_bmps, s_read_size);
  s_type = RFB_ENCODING_RICHCURSOR;
  rf_host_cursor();
  fbupdate_rect_done();
}
Example #6
0
static void rf_host_xcursor_color(void)
{
  CARD32 size;

  fbs_spool_data(cur_slot->readbuf, sz_rfbXCursorColors);

  /* calculate size of two cursor bitmaps to follow */
  size = ((s_new_curs_rect.w + 7) / 8) * s_new_curs_rect.h * 2;
  s_new_bmps = realloc(s_new_bmps, size);
  if (!s_new_bmps) {
    log_write(LL_ERROR, "Failed to allocate memory for cursor pixmaps");
    aio_close(0);
    return;
  }
  s_read_size = size;
  aio_setread(rf_host_xcursor_bmps, s_new_bmps, size);
}
static void rf_host_hextile_raw(void)
{
  int row;
  CARD32 *from_ptr;
  CARD32 *fb_ptr;

  fbs_spool_data(hextile_buf, s_tile.w * s_tile.h * sizeof(CARD32));

  from_ptr = hextile_buf;
  fb_ptr = &g_framebuffer[s_tile.y * (int)g_fb_width + s_tile.x];

  /* Just copy raw data into the framebuffer */
  for (row = 0; row < s_tile.h; row++) {
    memcpy(fb_ptr, from_ptr, s_tile.w * sizeof(CARD32));
    from_ptr += s_tile.w;
    fb_ptr += g_fb_width;
  }

  hextile_next_tile();
}
Example #8
0
static void rf_host_fbupdate_raw(void)
{
#ifdef CHROMIUM
  CARD32 *g_framebuffer;
  CARD16 g_fb_width, g_fb_height;
  g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height);
#endif

  fbs_spool_data(cur_slot->readbuf, cur_rect.w * sizeof(CARD32));

  if (++rect_cur_row < cur_rect.h) {
    /* Read next row */
    CARD32 *dst = PIXEL_ADDR(g_framebuffer, g_fb_width, g_fb_height,
                             cur_rect.x, cur_rect.y + rect_cur_row);
    aio_setread(rf_host_fbupdate_raw, dst,
                cur_rect.w * sizeof(CARD32));
  } else {
    /* Done with this rectangle */
    fbupdate_rect_done();
  }
}
Example #9
0
static void rf_host_fbupdate_recthdr(void)
{
  HOST_SLOT *hs = (HOST_SLOT *)cur_slot;
#ifdef CHROMIUM
  CARD32 *g_framebuffer;
  CARD16 g_fb_width, g_fb_height;
  g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height);
#endif

  cur_rect.x = buf_get_CARD16(cur_slot->readbuf);
  cur_rect.y = buf_get_CARD16(&cur_slot->readbuf[2]);
  cur_rect.w = buf_get_CARD16(&cur_slot->readbuf[4]);
  cur_rect.h = buf_get_CARD16(&cur_slot->readbuf[6]);
  cur_rect.enc = buf_get_CARD32(&cur_slot->readbuf[8]);

  fbs_spool_data(cur_slot->readbuf, 12);

  /* Handle LastRect "encoding" first */
  if (cur_rect.enc == RFB_ENCODING_LASTRECT) {
    log_write(LL_DEBUG, "LastRect marker received from the host");
    cur_rect.x = cur_rect.y = 0;
    rect_count = 1;
    fbupdate_rect_done();
    return;
  }

  /* Ignore zero-size rectangles */
  if (cur_rect.h == 0 || cur_rect.w == 0) {
    log_write(LL_WARN, "Zero-size rectangle %dx%d at %d,%d (ignoring)",
              (int)cur_rect.w, (int)cur_rect.h,
              (int)cur_rect.x, (int)cur_rect.y);
    fbupdate_rect_done();
    return;
  }

  /* Handle NewFBSize "encoding", as a special case */
  if (cur_rect.enc == RFB_ENCODING_NEWFBSIZE) {
    log_write(LL_INFO, "New host desktop geometry: %dx%d",
              (int)cur_rect.w, (int)cur_rect.h);
    g_screen_info.width = hs->fb_width = cur_rect.w;
    g_screen_info.height = hs->fb_height = cur_rect.h;

    /* Reallocate the framebuffer if necessary */
    if (!alloc_framebuffer(hs->fb_width, hs->fb_height)) {
      aio_close(1);
      return;
    }

    cur_rect.x = cur_rect.y = 0;

    /* NewFBSize is always the last rectangle regardless of rect_count */
    rect_count = 1;
    fbupdate_rect_done();
    return;
  }

  /* Prevent overflow of the framebuffer */
  if (cur_rect.x >= g_fb_width || cur_rect.x + cur_rect.w > g_fb_width ||
      cur_rect.y >= g_fb_height || cur_rect.y + cur_rect.h > g_fb_height) {
    log_write(LL_ERROR, "Rectangle out of framebuffer bounds: %dx%d at %d,%d",
              (int)cur_rect.w, (int)cur_rect.h,
              (int)cur_rect.x, (int)cur_rect.y);
    aio_close(0);
    return;
  }

  /* Ok, now the rectangle seems correct */
  log_write(LL_DEBUG, "Receiving rectangle %dx%d at %d,%d",
            (int)cur_rect.w, (int)cur_rect.h,
            (int)cur_rect.x, (int)cur_rect.y);

  switch(cur_rect.enc) {
  case RFB_ENCODING_RAW:
    log_write(LL_DEBUG, "Receiving raw data, expecting %d byte(s)",
              cur_rect.w * cur_rect.h * sizeof(CARD32));
    rect_cur_row = 0;
    aio_setread(rf_host_fbupdate_raw,
                PIXEL_ADDR(g_framebuffer, g_fb_width, g_fb_height,
                           cur_rect.x, cur_rect.y),
                cur_rect.w * sizeof(CARD32));
    break;
  case RFB_ENCODING_COPYRECT:
    log_write(LL_DEBUG, "Receiving CopyRect instruction");
    aio_setread(rf_host_copyrect, NULL, 4);
    break;
  case RFB_ENCODING_HEXTILE:
    log_write(LL_DEBUG, "Receiving Hextile-encoded data");
    setread_decode_hextile(&cur_rect);
    break;
  case RFB_ENCODING_TIGHT:
    log_write(LL_DEBUG, "Receiving Tight-encoded data");
    setread_decode_tight(&cur_rect);
    break;
  default:
    log_write(LL_ERROR, "Unknown encoding: 0x%08lX",
              (unsigned long)cur_rect.enc);
    aio_close(0);
  }
}