static void rf_host_msg(void) { int msg_id; msg_id = (int)cur_slot->readbuf[0] & 0xFF; switch(msg_id) { case rfbFramebufferUpdate: aio_setread(rf_host_fbupdate_hdr, NULL, 3); break; case rfbSetColourMapEntries: aio_setread(rf_host_colormap_hdr, NULL, 5); break; case rfbBell: log_write(LL_DETAIL, "Received Bell message from host"); fbs_write_data(cur_slot->readbuf, 1); aio_setread(rf_host_msg, NULL, 1); break; case rfbServerCutText: aio_setread(rf_host_cuttext_hdr, NULL, 7); break; default: log_write(LL_ERROR, "Unknown server message type: %d", msg_id); aio_close(0); } }
static void rf_client_msg(void) { int msg_id; msg_id = (int)cur_slot->readbuf[0] & 0xFF; switch(msg_id) { case rfbSetPixelFormat: aio_setread(rf_client_pixfmt, NULL, 3 + sizeof(RFB_PIXEL_FORMAT)); break; case rfbFixColourMapEntries: aio_setread(rf_client_colormap_hdr, NULL, 5); break; case rfbSetEncodings: aio_setread(rf_client_encodings_hdr, NULL, 3); break; case rfbFramebufferUpdateRequest: aio_setread(rf_client_updatereq, NULL, 9); break; case rfbKeyEvent: aio_setread(rf_client_keyevent, NULL, 7); break; case rfbPointerEvent: aio_setread(rf_client_ptrevent, NULL, 5); break; case rfbClientCutText: aio_setread(rf_client_cuttext_hdr, NULL, 7); break; default: log_write(LL_ERROR, "Unknown client message type %d from %s", msg_id, cur_slot->name); aio_close(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(); }
/* On-close hook */ void host_close_hook(void) { #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #endif if (cur_slot->type == TYPE_HOST_ACTIVE_SLOT) { /* Close session file if open */ fbs_close_file(); /* Erase framebuffer contents, invalidate cache */ /* FIXME: Don't reset if there is a new connection, so the framebuffer (of its new size) would be changed anyway? */ reset_framebuffer(); /* No active slot exist */ s_host_slot = NULL; } if (cur_slot->errread_f) { if (cur_slot->io_errno) { log_write(LL_ERROR, "Host I/O error, read: %s", strerror(cur_slot->io_errno)); } else { log_write(LL_ERROR, "Host I/O error, read"); } } else if (cur_slot->errwrite_f) { if (cur_slot->io_errno) { log_write(LL_ERROR, "Host I/O error, write: %s", strerror(cur_slot->io_errno)); } else { log_write(LL_ERROR, "Host I/O error, write"); } } else if (cur_slot->errio_f) { log_write(LL_ERROR, "Host I/O error"); } if (s_new_slot == NULL) { log_write(LL_WARN, "Closing connection to host"); /* Exit event loop if framebuffer does not exist yet. */ if (g_framebuffer == NULL) aio_close(1); remove_active_file(); } else { log_write(LL_INFO, "Closing previous connection to host"); host_really_activate(s_new_slot); s_new_slot = NULL; } }
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(); }
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_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; }
static void host_really_activate(AIO_SLOT *slot) { AIO_SLOT *saved_slot = cur_slot; HOST_SLOT *hs = (HOST_SLOT *)slot; log_write(LL_MSG, "Activating new host connection"); slot->type = TYPE_HOST_ACTIVE_SLOT; s_host_slot = slot; write_active_file(); perform_action("host_activate"); /* Allocate the framebuffer or extend its dimensions if necessary */ if (!alloc_framebuffer(hs->fb_width, hs->fb_height)) { aio_close(1); return; } /* Set default desktop geometry for new client connections */ g_screen_info.width = hs->fb_width; g_screen_info.height = hs->fb_height; /* If requested, open file to save this session and write the header */ fbs_open_file(hs->fb_width, hs->fb_height); cur_slot = slot; /* Reset zlib streams in the Tight decoder */ reset_tight_streams(); /* Request initial screen contents */ log_write(LL_DETAIL, "Requesting full framebuffer update"); request_update(0); aio_setread(rf_host_msg, NULL, 1); /* Notify clients about desktop geometry change */ aio_walk_slots(fn_host_pass_newfbsize, TYPE_CL_SLOT); cur_slot = saved_slot; }
void setread_decode_richcursor(FB_RECT *r) { CARD32 size; s_new_curs_rect = *r; if (s_new_curs_rect.w * s_new_curs_rect.h) { /* calculate size of two cursor bitmaps to follow */ /* cursor image in client pixel format */ /* transparency data for cursor */ size = s_new_curs_rect.w * s_new_curs_rect.h * (g_screen_info.pixformat.bits_pixel / 8); size += ((s_new_curs_rect.w + 7) / 8) * s_new_curs_rect.h; 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_richcursor_bmps, s_new_bmps, size); } }
void aioClose(int fd) { aio_ctrl_t *ctrlp; assert(initialised); aio_counts.close++; aioCancel(fd); ctrlp = memPoolAlloc(aio_ctrl_pool); ctrlp->fd = fd; ctrlp->done_handler = NULL; ctrlp->done_handler_data = NULL; ctrlp->operation = _AIO_CLOSE; if (aio_close(fd, &ctrlp->result) < 0) { close(fd); /* Can't create thread - do a normal close */ memPoolFree(aio_ctrl_pool, ctrlp); aioFDWasClosed(fd); return; } ctrlp->next = used_list; used_list = ctrlp; return; }
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); } }
static void wf_client_auth_failed(void) { aio_close(0); }