void transfunc_null(void *dst_buf, FB_RECT *r, void *table) { CARD32 *fb_ptr; CARD32 *dst_ptr = (CARD32 *)dst_buf; int y; #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #endif #if RASTER_BOTTOM_TO_TOP fb_ptr = g_framebuffer + (g_fb_height - 1 - r->y) * g_fb_width + r->x; for (y = 0; y < r->h; y++) { memcpy(dst_ptr, fb_ptr, r->w * sizeof(CARD32)); fb_ptr -= g_fb_width; dst_ptr += r->w; } #else fb_ptr = &g_framebuffer[r->y * g_fb_width + r->x]; for (y = 0; y < r->h; y++) { memcpy(dst_ptr, fb_ptr, r->w * sizeof(CARD32)); fb_ptr += g_fb_width; dst_ptr += r->w; } #endif }
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 save_ppm(const char *fname) { const GLubyte *buffer; CARD16 width, height; const int binary = 0; FILE *f = fopen( fname, "w" ); vnc_spu.screen_buffer_locked = 1; buffer = (GLubyte *) GetFrameBuffer(&width, &height); vnc_spu.screen_buffer_locked = 0; if (f) { int i, x, y; const GLubyte *ptr = buffer; if (binary) { fprintf(f,"P6\n"); fprintf(f,"# ppm-file created by osdemo.c\n"); fprintf(f,"%i %i\n", width,height); fprintf(f,"255\n"); fclose(f); f = fopen( fname, "ab" ); /* reopen in binary append mode */ for (y=0; y<height; y++) { for (x=0; x<width; x++) { i = (y*width + x) * 4; fputc(ptr[i+2], f); /* write red */ fputc(ptr[i+1], f); /* write green */ fputc(ptr[i+0], f); /* write blue */ } } } else { /*ASCII*/ int counter = 0; fprintf(f,"P3\n"); fprintf(f,"# ascii ppm file created by osdemo.c\n"); fprintf(f,"%i %i\n", width, height); fprintf(f,"255\n"); for (y=height-1; y>=0; y--) { for (x=0; x<width; x++) { i = (y*width + x) * 4; fprintf(f, " %3d %3d %3d", ptr[i+2], ptr[i+1], ptr[i+0]); counter++; if (counter % 5 == 0) fprintf(f, "\n"); } } } fclose(f); } }
void fill_fb_rect(FB_RECT *r, CARD32 color) { int x, y; CARD32 *fb_ptr; #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #endif fb_ptr = &g_framebuffer[r->y * (int)g_fb_width + r->x]; /* Fill the first row */ for (x = 0; x < r->w; x++) fb_ptr[x] = color; /* Copy the first row into all other rows */ for (y = 1; y < r->h; y++) memcpy(&fb_ptr[y * g_fb_width], fb_ptr, r->w * sizeof(CARD32)); }
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(); } }
/** * Pack 24bpp framebuffer data into 24bpp message */ void transfunc_null24(void *dst_buf, FB_RECT *r, void *table) { const CARD8 *fb_ptr; CARD8 *dst_ptr = (CARD8 *) dst_buf; const int w = r->w, h = r->h; int i; /* CHROMIUM */ CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); assert(RASTER_BOTTOM_TO_TOP==1);/*XXX FIX*/ /*assert(vnc_spu.pixel_size == 24);*/ fb_ptr = (CARD8 *) g_framebuffer + ((g_fb_height - 1 - r->y) * g_fb_width + r->x) * 3; for (i = 0; i < h; i++) { memcpy(dst_ptr, fb_ptr, w * 3); dst_ptr += w * 3; fb_ptr -= g_fb_width * 3; } }
static void reset_framebuffer(void) { HOST_SLOT *hs = (HOST_SLOT *)cur_slot; FB_RECT r; #ifdef CHROMIUM CARD32 *g_framebuffer; CARD16 g_fb_width, g_fb_height; g_framebuffer = GetFrameBuffer(&g_fb_width, &g_fb_height); #else log_write(LL_DETAIL, "Clearing framebuffer and cache"); memset(g_framebuffer, 0, g_fb_width * g_fb_height * sizeof(CARD32)); #endif r.x = r.y = 0; r.w = g_fb_width; r.h = g_fb_height; invalidate_enc_cache(&r); /* Queue changed rectangle (the whole host screen) for each client */ r.w = hs->fb_width; r.h = hs->fb_height; aio_walk_slots(fn_host_add_client_rect, TYPE_CL_SLOT); }
//------------------------------------------------------------------------------ // IDecklinkPushSource3 interface //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // GetFrameBuffer // Provide the caller with a free media sample. If there are no free samples, // all have been delivered downstream, block until one is returned to the free list. STDMETHODIMP CCustomAllocator::GetFrameBuffer(IUnknown** ppSample) { return GetFrameBuffer(reinterpret_cast<IMediaSample**>(ppSample)); }
void RenderPass::UseFrameBuffer(int at) { m_pCurFrameBuffer = GetFrameBuffer(at); }
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); } }