static int test_empty_rectangle(void) { REGION16 region, intersection; int retCode = -1; int i; RECTANGLE_16 emptyRectangles[3] = { { 0, 0, 0, 0}, { 10, 10, 10, 11}, { 10, 10, 11, 10} }; RECTANGLE_16 firstRect = { 0, 0, 100, 100 }; RECTANGLE_16 anotherRect = { 100, 100, 200, 200 }; RECTANGLE_16 expected_inter_extents = { 0, 0, 0, 0 }; region16_init(®ion); region16_init(&intersection); /* Check for empty rectangles */ for (i = 0; i < 3; i++) { if (!rectangle_is_empty(&emptyRectangles[i])) goto out; } /* Check for non-empty rectangles */ if (rectangle_is_empty(&firstRect)) goto out; /* Intersect 2 non-intersect rectangle, result should be empty */ if (!region16_union_rect(®ion, ®ion, &firstRect)) goto out; if (!region16_intersect_rect(®ion, ®ion, &anotherRect)) goto out; if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1)) goto out; if (!region16_is_empty(®ion)) goto out; if (!rectangle_is_empty(region16_extents(&intersection))) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
static int test_r1_r3_inter_r11(void) { REGION16 region, intersection; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r11 = {170, 151, 600, 301}; RECTANGLE_16 r1_r3_inter_r11[] = { {170, 151, 250, 251}, }; region16_init(®ion); region16_init(&intersection); /* * +=============================================================== * | * |+-----+ * || | * || +------+ * || r1+r3 | (r1+r3) & r11 * || +----------------+ +--------+ * |+---+ | | | ====> | | * | | | | | | | * | | | | | | | * | +-|------+ | +--------+ * | | r11 | * | +----------------+ * * * R1+R3 is made of 3 bands, R11 overlap the second and the third band. The * intersection is made of two band that must be reassembled to give only * one */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; if (!region16_intersects_rect(®ion, &r11)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &r11)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects)) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height) { rdpShadowSurface* surface; surface = (rdpShadowSurface*) calloc(1, sizeof(rdpShadowSurface)); if (!surface) return NULL; surface->server = server; surface->x = x; surface->y = y; surface->width = width; surface->height = height; surface->scanline = (surface->width + (surface->width % 4)) * 4; surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free (surface); return NULL; } if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000)) { free (surface->data); free (surface); return NULL; } region16_init(&(surface->invalidRegion)); return surface; }
static int test_r1_inter_r3(void) { REGION16 region, intersection; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r1_inter_r3[] = { {150, 151, 200, 201}, }; region16_init(®ion); region16_init(&intersection); /* * +=============================================================== * | * |+-----+ * || r1 | * || +-+------+ +-+ * || | r3 | r1&r3 | | * |+---+ | ====> +-+ * | | | * | +--------+ */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_intersects_rect(®ion, &r3)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &r3)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); region16_uninit(&intersection); return retCode; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->scanline = gfx_align_scanline(surface->width * 4, 16); surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32_t width, uint32_t height, enum wl_shm_format format) { int ret = UWAC_SUCCESS; UwacBuffer* newBuffers; int i, fd; void* data; struct wl_shm_pool* pool; newBuffers = realloc(w->buffers, (w->nbuffers + nbuffers) * sizeof(UwacBuffer)); if (!newBuffers) return UWAC_ERROR_NOMEMORY; w->buffers = newBuffers; memset(w->buffers + w->nbuffers, 0, sizeof(UwacBuffer) * nbuffers); fd = uwac_create_anonymous_file(allocSize * nbuffers); if (fd < 0) { return UWAC_ERROR_INTERNAL; } data = mmap(NULL, allocSize * nbuffers, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { ret = UWAC_ERROR_NOMEMORY; goto error_mmap; } pool = wl_shm_create_pool(w->display->shm, fd, allocSize * nbuffers); if (!pool) { ret = UWAC_ERROR_NOMEMORY; goto error_mmap; } for (i = 0; i < nbuffers; i++) { UwacBuffer* buffer = &w->buffers[w->nbuffers + i]; #ifdef HAVE_PIXMAN_REGION pixman_region32_init(&buffer->damage); #else region16_init(&buffer->damage); #endif buffer->data = data + (allocSize * i); buffer->wayland_buffer = wl_shm_pool_create_buffer(pool, allocSize * i, width, height, w->stride, format); wl_buffer_add_listener(buffer->wayland_buffer, &buffer_listener, buffer); } wl_shm_pool_destroy(pool); w->nbuffers += nbuffers; error_mmap: close(fd); return ret; }
int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) { xfContext* xfc = (xfContext*) context->custom; if (xfc->codecs->rfx) { rfx_context_free(xfc->codecs->rfx); xfc->codecs->rfx = NULL; } xfc->codecs->rfx = rfx_context_new(FALSE); xfc->codecs->rfx->width = resetGraphics->width; xfc->codecs->rfx->height = resetGraphics->height; rfx_context_set_pixel_format(xfc->codecs->rfx, RDP_PIXEL_FORMAT_B8G8R8A8); if (xfc->codecs->nsc) { nsc_context_free(xfc->codecs->nsc); xfc->codecs->nsc = NULL; } xfc->codecs->nsc = nsc_context_new(); xfc->codecs->nsc->width = resetGraphics->width; xfc->codecs->nsc->height = resetGraphics->height; nsc_context_set_pixel_format(xfc->codecs->nsc, RDP_PIXEL_FORMAT_B8G8R8A8); if (xfc->codecs->clear) { clear_context_free(xfc->codecs->clear); xfc->codecs->clear = NULL; } xfc->codecs->clear = clear_context_new(FALSE); if (xfc->codecs->h264) { h264_context_free(xfc->codecs->h264); xfc->codecs->h264 = NULL; } xfc->codecs->h264 = h264_context_new(FALSE); if (xfc->codecs->progressive) { progressive_context_free(xfc->codecs->progressive); xfc->codecs->progressive = NULL; } xfc->codecs->progressive = progressive_context_new(TRUE); region16_init(&(xfc->invalidRegion)); xfc->graphicsReset = TRUE; return 1; }
static int test_norbert_case() { REGION16 region, intersection; int retCode = -1; const RECTANGLE_16 *rects; int nbRects, i; RECTANGLE_16 inRectangles[5] = { {1680, 0, 1920, 242}, { 294, 242, 971, 776}, {1680, 242, 1920, 776}, {1680, 776, 1920, 1036}, { 2, 1040, 53, 1078} }; RECTANGLE_16 screenRect = { 0, 0, 1920, 1080 }; RECTANGLE_16 expected_inter_extents = { 0, 0, 1920, 1078 }; region16_init(®ion); region16_init(&intersection); for (i = 0; i < 5; i++) { if (!region16_union_rect(®ion, ®ion, &inRectangles[i])) goto out; } if (!region16_intersect_rect(&intersection, ®ion, &screenRect)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects)) goto out; if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) ) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
static int test_from_weston(void) { /* * 0: 0,0 -> 640,32 (w=640 h=32) * 1: 236,169 -> 268,201 (w=32 h=32) * 2: 246,258 -> 278,290 (w=32 h=32) */ REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 0, 640, 32}; RECTANGLE_16 r2 = {236, 169, 268, 201}; RECTANGLE_16 r3 = {246, 258, 278, 290}; RECTANGLE_16 r1_r2_r3[] = { { 0, 0, 640, 32}, {236, 169, 268, 201}, {246, 258, 278, 290} }; region16_init(®ion); /* * +=============================================================== * |+-------------------------------------------------------------+ * || r1 | * |+-------------------------------------------------------------+ * | * | +---------------+ * | | r2 | * | +---------------+ * | * | +---------------+ * | | r3 | * | +---------------+ * | */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r2)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
int gdi_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) { rdpGdi* gdi = (rdpGdi*) context->custom; freerdp_client_codecs_reset(gdi->codecs, FREERDP_CODEC_ALL); region16_init(&(gdi->invalidRegion)); gdi->graphicsReset = TRUE; return 1; }
static int test_r1_r2_r4(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r4 = {150, 251, 250, 301}; RECTANGLE_16 r1_r2_r4[] = { { 0, 101, 200, 201}, {150, 251, 250, 401} }; /* * +=============================================================== * | * |+-----+ +-----+ * || r1 | | | * || | | | * || | | | * |+-----+ ====> +-----+ * | * | +--------+ +--------+ * | | r4 | | | * | +--------+ | | * | | r2 | | | * | | | | | * | +--------+ +--------+ * */ region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r2)) goto out; if (!region16_union_rect(®ion, ®ion, &r4)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r1_r3() { REGION16 region; int retCode = -1; const RECTANGLE_16 *rects; int nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r1_r3[] = { { 0, 101, 200, 151}, { 0, 151, 250, 201}, {150, 201, 250, 251} }; region16_init(®ion); /* * +=============================================================== * | * |+-----+ +-----+ * || r1 | | | * || +-+------+ +-----+--------+ * || | r3 | | | * |+---+ | ====> +-----+--------+ * | | | | | * | +--------+ +--------+ */ /* R1 + R3 */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; /* R3 + R1 */ region16_clear(®ion); if (!region16_union_rect(®ion, ®ion, &r3)) goto out; if (!region16_union_rect(®ion, ®ion, &r1)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) { xfContext* xfc = (xfContext*) context->custom; freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL); region16_uninit(&(xfc->invalidRegion)); region16_init(&(xfc->invalidRegion)); xfc->graphicsReset = TRUE; return 1; }
BOOL wf_sw_end_paint(wfContext* wfc) { int i; rdpGdi* gdi; int ninvalid; RECT updateRect; HGDI_RGN cinvalid; REGION16 invalidRegion; RECTANGLE_16 invalidRect; const RECTANGLE_16* extents; rdpContext* context = (rdpContext*) wfc; gdi = context->gdi; ninvalid = gdi->primary->hdc->hwnd->ninvalid; cinvalid = gdi->primary->hdc->hwnd->cinvalid; if (ninvalid < 1) return TRUE; region16_init(&invalidRegion); for (i = 0; i < ninvalid; i++) { invalidRect.left = cinvalid[i].x; invalidRect.top = cinvalid[i].y; invalidRect.right = cinvalid[i].x + cinvalid[i].w; invalidRect.bottom = cinvalid[i].y + cinvalid[i].h; region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); } if (!region16_is_empty(&invalidRegion)) { extents = region16_extents(&invalidRegion); updateRect.left = extents->left; updateRect.top = extents->top; updateRect.right = extents->right; updateRect.bottom = extents->bottom; InvalidateRect(wfc->hwnd, &updateRect, FALSE); if (wfc->rail) wf_rail_invalidate_region(wfc, &invalidRegion); } region16_uninit(&invalidRegion); return TRUE; }
void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) { int index; int count; RECTANGLE_16 updateRect; RECTANGLE_16 windowRect; ULONG_PTR* pKeys = NULL; xfAppWindow* appWindow; const RECTANGLE_16* extents; REGION16 windowInvalidRegion; region16_init(&windowInvalidRegion); count = HashTable_GetKeys(xfc->railWindows, &pKeys); for (index = 0; index < count; index++) { appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]); if (appWindow) { windowRect.left = MAX(appWindow->x, 0); windowRect.top = MAX(appWindow->y, 0); windowRect.right = MAX(appWindow->x + appWindow->width, 0); windowRect.bottom = MAX(appWindow->y + appWindow->height, 0); region16_clear(&windowInvalidRegion); region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); if (!region16_is_empty(&windowInvalidRegion)) { extents = region16_extents(&windowInvalidRegion); updateRect.left = extents->left - appWindow->x; updateRect.top = extents->top - appWindow->y; updateRect.right = extents->right - appWindow->x; updateRect.bottom = extents->bottom - appWindow->y; if (appWindow) { xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, updateRect.right - updateRect.left, updateRect.bottom - updateRect.top); } } } } region16_uninit(&windowInvalidRegion); }
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) { REGION16 invalidRegion; RECTANGLE_16 invalidRect; invalidRect.left = uleft; invalidRect.top = utop; invalidRect.right = uright; invalidRect.bottom = ubottom; region16_init(&invalidRegion); region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); xf_rail_invalidate_region(xfc, &invalidRegion); region16_uninit(&invalidRegion); }
static int test_basic(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; /* R1 + R2 ==> disjointed rects */ RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r1_r2[] = { {0, 101, 200, 201}, {150, 301, 250, 401} }; /* r1 */ region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16))) goto out; /* r1 + r2 */ if (!region16_union_rect(®ion, ®ion, &r2)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects)) goto out; /* clear region */ region16_clear(®ion); region16_rects(®ion, &nbRects); if (nbRects) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; REGION16 invalidRegion; const RECTANGLE_16* rects; UINT32 nrRects, x; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } rfx_context_set_pixel_format(surface->codecs->rfx, cmd->format); region16_init(&invalidRegion); if (!rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length, cmd->left, cmd->top, surface->data, surface->format, surface->scanline, surface->height, &invalidRegion)) { WLog_ERR(TAG, "Failed to process RemoteFX message"); region16_uninit(&invalidRegion); return ERROR_INTERNAL_ERROR; } rects = region16_rects(&invalidRegion, &nrRects); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, nrRects, rects); for (x=0; x<nrRects; x++) region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &rects[x]); region16_uninit(&invalidRegion); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
static int test_r1_r5(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r5 = {150, 121, 300, 131}; RECTANGLE_16 r1_r5[] = { { 0, 101, 200, 121}, { 0, 121, 300, 131}, { 0, 131, 200, 201} }; region16_init(®ion); /* * +=============================================================== * | * |+--------+ +--------+ * || r1 | | | * || +--+----+ +--------+----+ * || | r5 | =====> | | * || +-------+ +--------+----+ * || | | | * |+--------+ +--------+ * | * */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r5)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r9_r10(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; /* * +=============================================================== * | * | +---+ +---+ * |+--|r10|-+ +--+---+-+ * ||r9| | | | | * || | | | | | * || | | | =====> | | * || | | | | | * || | | | | | * |+--| |-+ +--+---+-+ * | +---+ +---+ */ RECTANGLE_16 r9 = { 0, 100, 400, 200}; RECTANGLE_16 r10 = {200, 0, 300, 300}; RECTANGLE_16 r9_r10[] = { {200, 0, 300, 100}, { 0, 100, 400, 200}, {200, 200, 300, 300}, }; region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r9)) goto out; if (!region16_union_rect(®ion, ®ion, &r10)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion) { int index; int count; RECT updateRect; RECTANGLE_16 windowRect; ULONG_PTR* pKeys = NULL; wfRailWindow* railWindow; const RECTANGLE_16* extents; REGION16 windowInvalidRegion; region16_init(&windowInvalidRegion); count = HashTable_GetKeys(wfc->railWindows, &pKeys); for (index = 0; index < count; index++) { railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows, (void*) pKeys[index]); if (railWindow) { windowRect.left = railWindow->x; windowRect.top = railWindow->y; windowRect.right = railWindow->x + railWindow->width; windowRect.bottom = railWindow->y + railWindow->height; region16_clear(&windowInvalidRegion); region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); if (!region16_is_empty(&windowInvalidRegion)) { extents = region16_extents(&windowInvalidRegion); updateRect.left = extents->left - railWindow->x; updateRect.top = extents->top - railWindow->y; updateRect.right = extents->right - railWindow->x; updateRect.bottom = extents->bottom - railWindow->y; InvalidateRect(railWindow->hWnd, &updateRect, FALSE); } } } region16_uninit(&windowInvalidRegion); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT gdi_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free (surface); return CHANNEL_RC_NO_MEMORY; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; surface->format = (!gdi->invert) ? PIXEL_FORMAT_XRGB32 : PIXEL_FORMAT_XBGR32; surface->scanline = (surface->width + (surface->width % 4)) * 4; surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
rdpShadowScreen* shadow_screen_new(rdpShadowServer* server) { int x, y; int width, height; MONITOR_DEF* primary; rdpShadowScreen* screen; rdpShadowSubsystem* subsystem; screen = (rdpShadowScreen*) calloc(1, sizeof(rdpShadowScreen)); if (!screen) return NULL; screen->server = server; subsystem = server->subsystem; if (!InitializeCriticalSectionAndSpinCount(&(screen->lock), 4000)) return NULL; region16_init(&(screen->invalidRegion)); primary = &(subsystem->monitors[0]); x = primary->left; y = primary->top; width = primary->right - primary->left; height = primary->bottom - primary->top; screen->width = width; screen->height = height; screen->primary = shadow_surface_new(server, x, y, width, height); if (!screen->primary) return NULL; server->surface = screen->primary; return screen; }
static int test_r1_r6(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r6 = {150, 121, 170, 131}; region16_init(®ion); /* * +=============================================================== * | * |+--------+ +--------+ * || r1 | | | * || +--+ | | | * || |r6| | =====> | | * || +--+ | | | * || | | | * |+--------+ +--------+ * | */ region16_clear(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r6)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx) { xfc->gfx = gfx; gfx->custom = (void*) xfc; gfx->ResetGraphics = xf_ResetGraphics; gfx->StartFrame = xf_StartFrame; gfx->EndFrame = xf_EndFrame; gfx->SurfaceCommand = xf_SurfaceCommand; gfx->DeleteEncodingContext = xf_DeleteEncodingContext; gfx->CreateSurface = xf_CreateSurface; gfx->DeleteSurface = xf_DeleteSurface; gfx->SolidFill = xf_SolidFill; gfx->SurfaceToSurface = xf_SurfaceToSurface; gfx->SurfaceToCache = xf_SurfaceToCache; gfx->CacheToSurface = xf_CacheToSurface; gfx->CacheImportReply = xf_CacheImportReply; gfx->EvictCacheEntry = xf_EvictCacheEntry; gfx->MapSurfaceToOutput = xf_MapSurfaceToOutput; gfx->MapSurfaceToWindow = xf_MapSurfaceToWindow; region16_init(&(xfc->invalidRegion)); }
void gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx) { gdi->gfx = gfx; gfx->custom = (void*) gdi; gfx->ResetGraphics = gdi_ResetGraphics; gfx->StartFrame = gdi_StartFrame; gfx->EndFrame = gdi_EndFrame; gfx->SurfaceCommand = gdi_SurfaceCommand; gfx->DeleteEncodingContext = gdi_DeleteEncodingContext; gfx->CreateSurface = gdi_CreateSurface; gfx->DeleteSurface = gdi_DeleteSurface; gfx->SolidFill = gdi_SolidFill; gfx->SurfaceToSurface = gdi_SurfaceToSurface; gfx->SurfaceToCache = gdi_SurfaceToCache; gfx->CacheToSurface = gdi_CacheToSurface; gfx->CacheImportReply = gdi_CacheImportReply; gfx->EvictCacheEntry = gdi_EvictCacheEntry; gfx->MapSurfaceToOutput = gdi_MapSurfaceToOutput; gfx->MapSurfaceToWindow = gdi_MapSurfaceToWindow; region16_init(&(gdi->invalidRegion)); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; UINT32 bytesPerPixel; xfGfxSurface* surface; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->codecs = codecs_new((rdpContext*) xfc); if (!surface->codecs) { free (surface); return CHANNEL_RC_NO_MEMORY; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; surface->format = PIXEL_FORMAT_XRGB32; surface->scanline = surface->width * 4; surface->scanline += (surface->scanline % (xfc->scanline_pad / 8)); size = surface->scanline * surface->height; surface->data = (BYTE*) _aligned_malloc(size, 16); if (!surface->data) { free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->data, size); if ((xfc->depth == 24) || (xfc->depth == 32)) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->data, surface->width, surface->height, xfc->scanline_pad, surface->scanline); } else { bytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(xfc->format) / 8); surface->stageStep = surface->width * bytesPerPixel; surface->stageStep += (surface->stageStep % (xfc->scanline_pad / 8)); size = surface->stageStep * surface->height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { free(surface->data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->width, surface->height, xfc->scanline_pad, surface->stageStep); } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int i, j; int status; BYTE* DstData; RFX_RECT* rect; int nXDst, nYDst; int nXSrc, nYSrc; int nWidth, nHeight; int nbUpdateRects; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PROGRESSIVE, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); DstData = surface->data; status = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) { WLog_ERR(TAG, "progressive_decompress failure: %d", status); return ERROR_INTERNAL_ERROR; } region = &(surface->codecs->progressive->region); region16_init(&clippingRects); for (i = 0; i < region->numRects; i++) { rect = &(region->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < region->numTiles; i++) { tile = region->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; nXSrc = nXDst - (cmd->left + tile->x); nYSrc = nYDst - (cmd->top + tile->y); freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return ERROR_INTERNAL_ERROR; } region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(surface->codecs->rfx, message); region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; gdiGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; message = rfx_process_message(gdi->codecs->rfx, cmd->data, cmd->length); if (!message) return -1; region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(gdi->codecs->rfx, message); if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }