diff options
author | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
---|---|---|
committer | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
commit | cc3f33db7a8d3c4ad373e646b199808e01bc5d9b (patch) | |
tree | ec09d690c7656ab5f2cc72607e05fb359c24d8b2 /src/rdp/rdp_display_output.c |
added webrdp public code
Diffstat (limited to 'src/rdp/rdp_display_output.c')
-rw-r--r-- | src/rdp/rdp_display_output.c | 871 |
1 files changed, 871 insertions, 0 deletions
diff --git a/src/rdp/rdp_display_output.c b/src/rdp/rdp_display_output.c new file mode 100644 index 0000000..16f3c5d --- /dev/null +++ b/src/rdp/rdp_display_output.c @@ -0,0 +1,871 @@ +/* BSD-2-Clause license + * + * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>. + * + */ + +#include <freerdp/client/cmdline.h> +#include <freerdp/client/file.h> +#include <freerdp/constants.h> +#include <freerdp/freerdp.h> +#include <freerdp/gdi/gdi.h> +#include <freerdp/log.h> +#include <winpr/crt.h> +#include <winpr/synch.h> + +#include <webrdp_core_api.h> +#include <webrdp_module_api.h> + +#include "rdp_backend_api.h" +#include "rdp_impl.h" +#include "rdp_png.h" + +#define RGB_555_888(_r, _g, _b) \ + _r = (_r << 3 & ~0x7) | (_r >> 2); \ + _g = (_g << 3 & ~0x7) | (_g >> 2); \ + _b = (_b << 3 & ~0x7) | (_b >> 2); +#define RGB_565_888(_r, _g, _b) \ + _r = (_r << 3 & ~0x7) | (_r >> 2); \ + _g = (_g << 2 & ~0x3) | (_g >> 4); \ + _b = (_b << 3 & ~0x7) | (_b >> 2); +#define GetRGB_555(_r, _g, _b, _p) \ + _r = (_p & 0x7C00) >> 10; \ + _g = (_p & 0x3E0) >> 5; \ + _b = (_p & 0x1F); +#define GetRGB_565(_r, _g, _b, _p) \ + _r = (_p & 0xF800) >> 11; \ + _g = (_p & 0x7E0) >> 5; \ + _b = (_p & 0x1F); +#define GetRGB15(_r, _g, _b, _p) \ + GetRGB_555(_r, _g, _b, _p); \ + RGB_555_888(_r, _g, _b); +#define GetRGB16(_r, _g, _b, _p) \ + GetRGB_565(_r, _g, _b, _p); \ + RGB_565_888(_r, _g, _b); +#define RGB24(_r, _g, _b) ((_r << 16) | (_g << 8) | _b) +#define GetRGB24(_r, _g, _b, _p) \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); +#define GetRGB32(_r, _g, _b, _p) \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); +#define ARGB32(_a, _r, _g, _b) (_a << 24) | (_r << 16) | (_g << 8) | _b +#define RGB16(_r, _g, _b) \ + (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) \ + | ((_b >> 3) & 0x1F) +#define RGB15(_r, _g, _b) \ + (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) \ + | ((_b >> 3) & 0x1F) +#define GetARGB32(_a, _r, _g, _b, _p) \ + _a = (_p & 0xFF000000) >> 24; \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); + +HCLRCONV +freerdp_clrconv_new(UINT32 flags) +{ + HCLRCONV clrconv; + + clrconv = (CLRCONV *)calloc(1, sizeof(CLRCONV)); + + if (!clrconv) + { + perror("calloc"); + return 0; + } + + clrconv->alpha = (flags & CLRCONV_ALPHA) ? TRUE : FALSE; + clrconv->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE; + clrconv->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE; + + clrconv->palette = (rdpPalette *)calloc(1, sizeof(rdpPalette)); + + if (!clrconv->palette) + { + perror("calloc"); + free(clrconv); + return 0; + } + + return clrconv; +} + +void +freerdp_clrconv_free(HCLRCONV clrconv) +{ + if (clrconv) + { + free(clrconv->palette); + free(clrconv); + } +} + +static int +freerdp_get_pixel(BYTE *data, int x, int y, int width, int height, int bpp) +{ + int start; + int shift; + UINT16 *src16; + UINT32 *src32; + int red, green, blue; + + switch (bpp) + { + case 1: + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; + case 8: + return data[y * width + x]; + case 15: + case 16: + src16 = (UINT16 *)data; + return src16[y * width + x]; + case 24: + data += y * width * 3; + data += x * 3; + red = data[0]; + green = data[1]; + blue = data[2]; + return RGB24(red, green, blue); + case 32: + src32 = (UINT32 *)data; + return src32[y * width + x]; + default: + break; + } + + return 0; +} + +static void +freerdp_set_pixel( + BYTE *data, int x, int y, int width, int height, int bpp, int pixel) +{ + int start; + int shift; + int *dst32; + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + if (pixel) + data[start] = data[start] | (0x80 >> shift); + else + data[start] = data[start] & ~(0x80 >> shift); + } + else if (bpp == 32) + { + dst32 = (int *)data; + dst32[y * width + x] = pixel; + } +} + +static void +freerdp_color_split_rgb(UINT32 *color, int bpp, BYTE *red, BYTE *green, + BYTE *blue, BYTE *alpha, HCLRCONV clrconv) +{ + *red = *green = *blue = 0; + *alpha = (clrconv->alpha) ? 0xFF : 0x00; + + switch (bpp) + { + case 32: + if (clrconv->alpha) + { + GetARGB32(*alpha, *red, *green, *blue, *color); + } + else + { + GetRGB32(*red, *green, *blue, *color); + } + break; + + case 24: + GetRGB24(*red, *green, *blue, *color); + break; + + case 16: + GetRGB16(*red, *green, *blue, *color); + break; + + case 15: + GetRGB15(*red, *green, *blue, *color); + break; + + case 8: + *color &= 0xFF; + *red = clrconv->palette->entries[*color].red; + *green = clrconv->palette->entries[*color].green; + *blue = clrconv->palette->entries[*color].blue; + break; + + case 1: + if (*color != 0) + { + *red = 0xFF; + *green = 0xFF; + *blue = 0xFF; + } + break; + + default: + break; + } +} + +static void +freerdp_color_make_rgb(UINT32 *color, int bpp, BYTE *red, BYTE *green, + BYTE *blue, BYTE *alpha, HCLRCONV clrconv) +{ + switch (bpp) + { + case 32: + *color = ARGB32(*alpha, *red, *green, *blue); + break; + + case 24: + *color = RGB24(*red, *green, *blue); + break; + + case 16: + if (clrconv->rgb555) + { + *color = RGB15(*red, *green, *blue); + } + else + { + *color = RGB16(*red, *green, *blue); + } + break; + + case 15: + *color = RGB15(*red, *green, *blue); + break; + + case 8: + *color = RGB24(*red, *green, *blue); + break; + + case 1: + if ((*red != 0) || (*green != 0) || (*blue != 0)) + *color = 1; + break; + + default: + break; + } +} + +static UINT32 +freerdp_color_convert_rgb( + UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + BYTE red = 0; + BYTE green = 0; + BYTE blue = 0; + BYTE alpha = 0xFF; + UINT32 dstColor = 0; + + freerdp_color_split_rgb( + &srcColor, srcBpp, &red, &green, &blue, &alpha, clrconv); + freerdp_color_make_rgb( + &dstColor, dstBpp, &red, &green, &blue, &alpha, clrconv); + + return dstColor; +} + +static void +freerdp_alpha_cursor_convert(BYTE *alphaData, BYTE *xorMask, BYTE *andMask, + int width, int height, int bpp, HCLRCONV clrconv) +{ + UINT32 xorPixel; + UINT32 andPixel; + UINT32 x, y, jj; + + for (y = 0; y < height; y++) + { + jj = (bpp == 1) ? y : (height - 1) - y; + + for (x = 0; x < width; x++) + { + xorPixel = freerdp_get_pixel( + xorMask, x, jj, width, height, bpp); + xorPixel = freerdp_color_convert_rgb( + xorPixel, bpp, 32, clrconv); + andPixel = freerdp_get_pixel( + andMask, x, jj, width, height, 1); + + if (andPixel) + { + if ((xorPixel & 0xFFFFFF) == 0xFFFFFF) + { + /* use pattern (not solid black) for xor + * area */ + xorPixel = (x & 1) == (y & 1); + xorPixel = xorPixel ? 0xFFFFFF : 0; + xorPixel |= 0xFF000000; + } + else if (xorPixel == 0xFF000000) + { + xorPixel = 0; + } + } + + freerdp_set_pixel( + alphaData, x, y, width, height, 32, xorPixel); + } + } +} + +static void +freerdp_bitmap_flip(BYTE *src, BYTE *dst, int scanLineSz, int height) +{ + int i; + + BYTE *bottomLine = dst + (scanLineSz * (height - 1)); + BYTE *topLine = src; + + /* Special processing if called for flip-in-place. */ + if (src == dst) + { + /* Allocate a scanline buffer. + * (FIXME: malloc / xfree below should be replaced by "get/put + * scanline buffer from a pool/Q of fixed buffers" to reuse + * fixed size buffers (of max scanline size (or adaptative?) ) + * -- would be much faster). + */ + BYTE *tmpBfr = (BYTE *)winpr_aligned_malloc(scanLineSz, 16); + if (!tmpBfr) + { + return; + } + int half = height / 2; + /* Flip buffer in place by line permutations through the temp + * scan line buffer. + * Note that if height has an odd number of line, we don't need + * to move the center scanline anyway. + * Also note that in place flipping takes three memcpy() calls + * to process two scanlines while src to distinct dest would + * only requires two memcpy() calls for two scanlines. + */ + height--; + for (i = 0; i < half; i++) + { + CopyMemory(tmpBfr, topLine, scanLineSz); + CopyMemory(topLine, bottomLine, scanLineSz); + CopyMemory(bottomLine, tmpBfr, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + height--; + } + winpr_aligned_free(tmpBfr); + } + /* Flip from source buffer to destination buffer. */ + else + { + for (i = 0; i < height; i++) + { + if (bottomLine && topLine && scanLineSz) + { + CopyMemory(bottomLine, topLine, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + } + } + } +} + +static BYTE * +freerdp_image_flip(BYTE *srcData, BYTE *dstData, int width, int height, int bpp) +{ + int scanline; + + scanline = width * ((bpp + 7) / 8); + + if (!dstData) + dstData = (BYTE *)winpr_aligned_malloc( + width * height * ((bpp + 7) / 8), 16); + + if (!dstData) + { + return NULL; + } + + freerdp_bitmap_flip(srcData, dstData, scanline, height); + + return dstData; +} + +/* outgoing rdp protocol to client implementation */ + +static BOOL +Pointer_New(rdpContext *context, rdpPointer *pointer) +{ + my_rdp_context *c = (my_rdp_context *)context; + HCLRCONV hclrconv = c->my_internals->clrconv; + size_t psize = pointer->width * pointer->height * 4; + + my_rdp_pointer *p = (my_rdp_pointer *)pointer; + p->id = c->my_internals->m_ptrId++; + uint8_t *pixels = malloc(sizeof(uint8_t) * psize); + if (!pixels) + { + perror("malloc"); + return FALSE; + } + memset(pixels, 0, psize); + if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0)) + { + //XXX + freerdp_alpha_cursor_convert(pixels, pointer->xorMaskData, + pointer->andMaskData, pointer->width, pointer->height, + pointer->xorBpp, hclrconv); + } + + //check if the cursor is fully transparent + bool transparent = TRUE; + for (int y = 0; y < pointer->height; y++) + { + for (int x = 0; x < pointer->width; x++) + { + if (pixels[0 + x * 4 + y * 4 * pointer->width] != 0) + { + transparent = FALSE; + } + } + } + if (transparent) + { + pixels[3] = 1; + } + + rdp_png_buf png_buf; + memset(&png_buf, 0, sizeof(png_buf)); + png_buf.buf_size + = (pointer->width * pointer->height * sizeof(uint32_t)) + + 8 /* allocating fullsize 32but argb pixels + png header */; + png_buf.buf = malloc(png_buf.buf_size); + if (!png_buf.buf) + { + free(pixels); + perror("malloc"); + return FALSE; + } + png_generate_from_argb( + pointer->width, pointer->height, pixels, &png_buf); + + wrdp_core_display_cursor cur = {0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + (unsigned char)pointer->width, (unsigned char)pointer->height, 0x00, + 0x00, (unsigned char)pointer->xPos, + (unsigned char)(pointer->xPos >> 8), (unsigned char)pointer->yPos, + (unsigned char)(pointer->yPos >> 8), (unsigned char)png_buf.written, + (unsigned char)(png_buf.written >> 8), + (unsigned char)(png_buf.written >> 16), + (unsigned char)(png_buf.written >> 24), 0x16, 0x00, 0x00, 0x00}; + + cur.data = png_buf.buf; + wrdp_core_display_cursor_info cursor_info + = {p->id, pointer->xPos, pointer->yPos, png_buf.written, &cur}; + + c->my_internals->core->api_paint->send_ptr_new( + &cursor_info, c->my_internals->task_info); + free(png_buf.buf); + free(pixels); + return TRUE; +} + +static void +Pointer_Free(rdpContext *context, rdpPointer *pointer) +{ + my_rdp_pointer *p = (my_rdp_pointer *)pointer; + my_rdp_context *c = (my_rdp_context *)context; + if (p->id) + { + c->my_internals->core->api_paint->send_ptr_free( + p->id, c->my_internals->task_info); + } +} + +static BOOL +Pointer_Set(rdpContext *context, rdpPointer *pointer) +{ + my_rdp_pointer *p = (my_rdp_pointer *)pointer; + my_rdp_context *c = (my_rdp_context *)context; + c->my_internals->core->api_paint->send_ptr_set( + p->id, c->my_internals->task_info); + return TRUE; +} + +static BOOL +Pointer_SetNull(rdpContext *context) +{ + my_rdp_context *c = (my_rdp_context *)context; + c->my_internals->core->api_paint->send_ptr_set_null( + c->my_internals->task_info); + return TRUE; +} + +static BOOL +Pointer_SetDefault(rdpContext *context) +{ + my_rdp_context *c = (my_rdp_context *)context; + c->my_internals->core->api_paint->send_ptr_set_default( + c->my_internals->task_info); + return TRUE; +} + +void +register_pointer(rdpPointer *p) +{ + p->New = Pointer_New; + p->Free = Pointer_Free; + p->Set = Pointer_Set; + p->SetNull = Pointer_SetNull; + p->SetDefault = Pointer_SetDefault; +} + +static BOOL +BeginPaint(rdpContext *context) +{ + my_rdp_context *c = (my_rdp_context *)context; + c->my_internals->core->api_paint->send_begin_paint( + c->my_internals->task_info); + return TRUE; +} + +static BOOL +EndPaint(rdpContext *context) +{ + my_rdp_context *c = (my_rdp_context *)context; + c->my_internals->core->api_paint->send_end_paint( + c->my_internals->task_info); + return TRUE; +} + +static BOOL +SetBounds(rdpContext *context, const rdpBounds *bounds) +{ + my_rdp_context *c = (my_rdp_context *)context; + wrdp_core_display_bounds lB; + if (bounds) + { + lB.left = bounds->left; + lB.right = bounds->right + 1; + lB.top = bounds->top; + lB.bottom = bounds->bottom + 1; + } + else + { + memset(&lB, 0, sizeof(wrdp_core_display_bounds)); + } + c->my_internals->core->api_paint->send_set_bounds( + &lB, c->my_internals->task_info); + return TRUE; +} + +static BOOL +Synchronize(rdpContext *context) +{ + return TRUE; +} + +static BOOL +DesktopResize(rdpContext *context) +{ + my_rdp_context *c = (my_rdp_context *)context; + char buf[64]; + snprintf(buf, 63, "R:%dx%d", context->settings->DesktopWidth, + context->settings->DesktopHeight); + c->my_internals->core->api_msgs->send_text_msg( + buf, c->my_internals->task_info); + return TRUE; +} + +static BOOL +BitmapUpdate(rdpContext *context, const BITMAP_UPDATE *bitmap) +{ + my_rdp_context *c = (my_rdp_context *)context; + int i; + BITMAP_DATA *bmd; + for (i = 0; i < (int)bitmap->number; i++) + { + bmd = &bitmap->rectangles[i]; + wrdp_core_display_bmp bmp = {bmd->destLeft, bmd->destTop, + bmd->width, bmd->height, bmd->destRight - bmd->destLeft + 1, + bmd->destBottom - bmd->destTop + 1, bmd->bitsPerPixel, + bmd->compressed, bmd->bitmapLength}; + if (!bmd->compressed) + { + freerdp_image_flip(bmd->bitmapDataStream, + bmd->bitmapDataStream, bmd->width, bmd->height, + bmd->bitsPerPixel); + } + c->my_internals->core->api_paint->send_bitmap( + &bmp, bmd->bitmapDataStream, c->my_internals->task_info); + } + return TRUE; +} + +static BOOL +Palette(rdpContext *c, const PALETTE_UPDATE *p) +{ + return TRUE; +} + +static BOOL +PlaySound(rdpContext *c, const PLAY_SOUND_UPDATE *s) +{ + return TRUE; +} + +static BOOL +RefreshRect(rdpContext *c, UINT8 hz, const RECTANGLE_16 *r) +{ + return TRUE; +} + +static BOOL +SuppressOutput(rdpContext *c, UINT8 hz, const RECTANGLE_16 *r) +{ + return TRUE; +} + +/*static BOOL +SurfaceCommand(rdpContext* c, wStream* s) +{ + return TRUE; +}*/ + +static BOOL +SurfaceBits(rdpContext *c, const SURFACE_BITS_COMMAND *sbc) +{ + return TRUE; +} + +/*static BOOL +SurfaceFrameMarker(rdpContext* c, SURFACE_FRAME_MARKER* sfm) +{ + return TRUE; +} */ + +void +RegisterUpdate(freerdp *rdp) +{ + rdpUpdate *u = rdp->context->update; + u->BeginPaint = BeginPaint; + u->EndPaint = EndPaint; + u->SetBounds = SetBounds; + u->Synchronize = Synchronize; + u->DesktopResize = DesktopResize; + u->BitmapUpdate = BitmapUpdate; + u->Palette = Palette; + u->PlaySound = PlaySound; + u->SurfaceBits = SurfaceBits; + + u->RefreshRect = RefreshRect; + u->SuppressOutput = SuppressOutput; +} + +static BOOL +DstBlt(rdpContext *c, const DSTBLT_ORDER *_do) +{ + return TRUE; +} + +static BOOL +PatBlt(rdpContext *ctx, PATBLT_ORDER *po) +{ + my_rdp_context *c = (my_rdp_context *)ctx; + uint32_t rop3 = gdi_rop3_code(po->bRop); + if (GDI_BS_SOLID == po->brush.style) + { + wrdp_core_display_patblt_order patblt + = {po->nLeftRect, po->nTopRect, po->nWidth, po->nHeight, + FreeRDPConvertColor(po->foreColor, PIXEL_FORMAT_BGR16, + PIXEL_FORMAT_ABGR32, + NULL), //XXX + rop3}; + c->my_internals->core->api_paint->send_pat_blt( + &patblt, c->my_internals->task_info); + } + return TRUE; +} + +static BOOL +ScrBlt(rdpContext *ctx, const SCRBLT_ORDER *sbo) +{ + my_rdp_context *c = (my_rdp_context *)ctx; + uint32_t rop3 = gdi_rop3_code(sbo->bRop); + wrdp_core_display_scr_blt scr_blt = {rop3, sbo->nLeftRect, + sbo->nTopRect, sbo->nWidth, sbo->nHeight, sbo->nXSrc, sbo->nYSrc}; + c->my_internals->core->api_paint->send_scr_blt( + &scr_blt, c->my_internals->task_info); + return TRUE; +} + +static BOOL +OpaqueRect(rdpContext *context, const OPAQUE_RECT_ORDER *oro) +{ + my_rdp_context *c = (my_rdp_context *)context; + wrdp_core_display_opaque_rect_order oro2; + oro2.color = oro->color; + oro2.nHeight = oro->nHeight; + oro2.nLeftRect = oro->nLeftRect; + oro2.nTopRect = oro->nTopRect; + oro2.nWidth = oro->nWidth; + oro2.color = FreeRDPConvertColor( + oro2.color, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_ABGR32, NULL); + c->my_internals->core->api_paint->send_opaque_rect_order( + &oro2, c->my_internals->task_info); + return TRUE; +} + +static BOOL +DrawNineGrid(rdpContext *c, const DRAW_NINE_GRID_ORDER *dngo) +{ + return TRUE; +} + +static BOOL +MultiDstBlt(rdpContext *c, const MULTI_DSTBLT_ORDER *mdo) +{ + return TRUE; +} + +static BOOL +MultiPatBlt(rdpContext *c, const MULTI_PATBLT_ORDER *mpo) +{ + return TRUE; +} + +static BOOL +MultiScrBlt(rdpContext *c, const MULTI_SCRBLT_ORDER *mso) +{ + return TRUE; +} + +static BOOL +MultiOpaqueRect(rdpContext *context, const MULTI_OPAQUE_RECT_ORDER *moro) +{ + my_rdp_context *c = (my_rdp_context *)context; + wrdp_core_display_m_opaque_rect mrect; + mrect.color = FreeRDPConvertColor( + moro->color, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_ABGR32, NULL); + mrect.num_rect = moro->numRectangles; + mrect.rects = (wrdp_core_display_delta_rect *)(moro->rectangles); + c->my_internals->core->api_paint->send_multi_opaque_rect( + &mrect, c->my_internals->task_info); + return TRUE; +} + +static BOOL +MultiDrawNineGrid(rdpContext *c, const MULTI_DRAW_NINE_GRID_ORDER *mdngo) +{ + return TRUE; +} + +static BOOL +LineTo(rdpContext *c, const LINE_TO_ORDER *lto) +{ + return TRUE; +} + +static BOOL +Polyline(rdpContext *c, const POLYLINE_ORDER *po) +{ + return TRUE; +} + +static BOOL +MemBlt(rdpContext *c, MEMBLT_ORDER *mo) +{ + return TRUE; +} + +static BOOL +Mem3Blt(rdpContext *c, MEM3BLT_ORDER *mo) +{ + return TRUE; +} + +static BOOL +SaveBitmap(rdpContext *c, const SAVE_BITMAP_ORDER *sbo) +{ + return TRUE; +} + +static BOOL +GlyphIndex(rdpContext *c, GLYPH_INDEX_ORDER *gio) +{ + return TRUE; +} + +static BOOL +FastIndex(rdpContext *c, const FAST_INDEX_ORDER *fio) +{ + return TRUE; +} + +static BOOL +FastGlyph(rdpContext *c, const FAST_GLYPH_ORDER *fgo) +{ + return TRUE; +} + +static BOOL +PolygonSC(rdpContext *c, const POLYGON_SC_ORDER *pso) +{ + return TRUE; +} + +static BOOL +PolygonCB(rdpContext *c, POLYGON_CB_ORDER *pco) +{ + return TRUE; +} + +static BOOL +EllipseSC(rdpContext *c, const ELLIPSE_SC_ORDER *eso) +{ + return TRUE; +} + +static BOOL +EllipseCB(rdpContext *c, const ELLIPSE_CB_ORDER *eco) +{ + return TRUE; +} +void +RegisterPrimary(freerdp *rdp) +{ + rdpPrimaryUpdate *p = rdp->context->update->primary; + p->DstBlt = DstBlt; + p->PatBlt = PatBlt; + p->ScrBlt = ScrBlt; + p->OpaqueRect = OpaqueRect; + p->DrawNineGrid = DrawNineGrid; + p->MultiDstBlt = MultiDstBlt; + p->MultiPatBlt = MultiPatBlt; + p->MultiScrBlt = MultiScrBlt; + p->MultiOpaqueRect = MultiOpaqueRect; + p->MultiDrawNineGrid = MultiDrawNineGrid; + p->LineTo = LineTo; + p->Polyline = Polyline; + p->MemBlt = MemBlt; + p->Mem3Blt = Mem3Blt; + p->SaveBitmap = SaveBitmap; + p->GlyphIndex = GlyphIndex; + p->FastIndex = FastIndex; + p->FastGlyph = FastGlyph; + p->PolygonSC = PolygonSC; + p->PolygonCB = PolygonCB; + p->EllipseSC = EllipseSC; + p->EllipseCB = EllipseCB; +} |