int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) { int count; int status; int x, y; int width, height; XImage* image; rdpShadowScreen* screen; rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; const RECTANGLE_16 *extents; server = subsystem->server; surface = server->surface; screen = server->screen; count = ArrayList_Count(server->clients); if (count < 1) return 1; if ((count == 1) && subsystem->suppressOutput) return 1; surfaceRect.left = 0; surfaceRect.top = 0; surfaceRect.right = surface->width; surfaceRect.bottom = surface->height; XLockDisplay(subsystem->display); if (subsystem->use_xshm) { image = subsystem->fb_image; XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect); } else { image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap); status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) image->data, image->bytes_per_line, &invalidRect); } XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect); if (!region16_is_empty(&(subsystem->invalidRegion))) { extents = region16_extents(&(subsystem->invalidRegion)); x = extents->left; y = extents->top; width = extents->right - extents->left; height = extents->bottom - extents->top; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x, y, width, height, (BYTE*) image->data, PIXEL_FORMAT_XRGB32, image->bytes_per_line, x, y, NULL); //x11_shadow_blend_cursor(subsystem); count = ArrayList_Count(server->clients); InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); SetEvent(subsystem->updateEvent); EnterSynchronizationBarrier(&(subsystem->barrier), 0); DeleteSynchronizationBarrier(&(subsystem->barrier)); if (count == 1) { rdpShadowClient* client; client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0); if (client) { subsystem->captureFrameRate = client->encoder->fps; } } ResetEvent(subsystem->updateEvent); region16_clear(&(subsystem->invalidRegion)); } if (!subsystem->use_xshm) XDestroyImage(image); return 1; }
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) { int count; int status; int x, y; int width, height; XImage* image; rdpShadowScreen* screen; rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 invalidRect; server = subsystem->server; surface = server->surface; screen = server->screen; count = ArrayList_Count(server->clients); if (count < 1) return 1; if (subsystem->use_xshm) { XLockDisplay(subsystem->display); XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); image = subsystem->fb_image; status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect); if (status > 0) { x = invalidRect.left; y = invalidRect.top; width = invalidRect.right - invalidRect.left; height = invalidRect.bottom - invalidRect.top; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x - surface->x, y - surface->y, width, height, (BYTE*) image->data, PIXEL_FORMAT_XRGB32, image->bytes_per_line, x, y, NULL); region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); x11_shadow_blend_cursor(subsystem); count = ArrayList_Count(server->clients); InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); SetEvent(subsystem->updateEvent); EnterSynchronizationBarrier(&(subsystem->barrier), 0); DeleteSynchronizationBarrier(&(subsystem->barrier)); ResetEvent(subsystem->updateEvent); region16_clear(&(subsystem->invalidRegion)); } } else { XLockDisplay(subsystem->display); image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap); XUnlockDisplay(subsystem->display); status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) image->data, image->bytes_per_line, &invalidRect); if (status > 0) { x = invalidRect.left; y = invalidRect.top; width = invalidRect.right - invalidRect.left; height = invalidRect.bottom - invalidRect.top; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x, y, width, height, (BYTE*) image->data, PIXEL_FORMAT_XRGB32, image->bytes_per_line, x, y, NULL); region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); x11_shadow_blend_cursor(subsystem); count = ArrayList_Count(server->clients); InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); SetEvent(subsystem->updateEvent); EnterSynchronizationBarrier(&(subsystem->barrier), 0); DeleteSynchronizationBarrier(&(subsystem->barrier)); ResetEvent(subsystem->updateEvent); region16_clear(&(subsystem->invalidRegion)); } XDestroyImage(image); } return 1; }