Merge branch 'master' of github.com:FreeRDP/FreeRDP
This commit is contained in:
commit
06330a7cb3
@ -73,15 +73,15 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXclear;
|
||||
break;
|
||||
|
||||
case 0x000500A9:
|
||||
case GDI_DPon:
|
||||
function = GXnor;
|
||||
break;
|
||||
|
||||
case 0x000A0329:
|
||||
case GDI_DPna:
|
||||
function = GXandInverted;
|
||||
break;
|
||||
|
||||
case 0x000F0001:
|
||||
case GDI_Pn:
|
||||
function = GXcopyInverted;
|
||||
break;
|
||||
|
||||
@ -101,7 +101,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXandReverse;
|
||||
break;
|
||||
|
||||
case 0x00500325:
|
||||
case GDI_PDna:
|
||||
function = GXandReverse;
|
||||
break;
|
||||
|
||||
@ -113,7 +113,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXxor;
|
||||
break;
|
||||
|
||||
case 0x005F00E9:
|
||||
case GDI_DPan:
|
||||
function = GXnand;
|
||||
break;
|
||||
|
||||
@ -121,7 +121,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXxor;
|
||||
break;
|
||||
|
||||
case 0x007700E6:
|
||||
case GDI_DSan:
|
||||
function = GXnand;
|
||||
break;
|
||||
|
||||
@ -129,11 +129,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXand;
|
||||
break;
|
||||
|
||||
case 0x00990066:
|
||||
case GDI_DSxn:
|
||||
function = GXequiv;
|
||||
break;
|
||||
|
||||
case 0x00A000C9:
|
||||
case GDI_DPa:
|
||||
function = GXand;
|
||||
break;
|
||||
|
||||
@ -141,11 +141,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXequiv;
|
||||
break;
|
||||
|
||||
case 0x00AA0029:
|
||||
case GDI_D:
|
||||
function = GXnoop;
|
||||
break;
|
||||
|
||||
case 0x00AF0229:
|
||||
case GDI_DPno:
|
||||
function = GXorInverted;
|
||||
break;
|
||||
|
||||
@ -157,7 +157,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXcopy;
|
||||
break;
|
||||
|
||||
case 0x00DD0228:
|
||||
case GDI_SDno:
|
||||
function = GXorReverse;
|
||||
break;
|
||||
|
||||
@ -169,11 +169,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXcopy;
|
||||
break;
|
||||
|
||||
case 0x00F50225:
|
||||
case GDI_PDno:
|
||||
function = GXorReverse;
|
||||
break;
|
||||
|
||||
case 0x00FA0089:
|
||||
case GDI_DPo:
|
||||
function = GXor;
|
||||
break;
|
||||
|
||||
@ -181,6 +181,10 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
function = GXset;
|
||||
break;
|
||||
|
||||
case GDI_PSDPxax:
|
||||
function = GXand;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -205,17 +209,19 @@ Pixmap xf_brush_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
|
||||
|
||||
bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, xfi->depth);
|
||||
|
||||
if(data != NULL)
|
||||
if (data != NULL)
|
||||
{
|
||||
GC gc; // FIXME, should cache
|
||||
GC gc;
|
||||
|
||||
cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
|
||||
ZPixmap, 0, (char*) cdata, width, height, xfi->scanline_pad, 0);
|
||||
|
||||
gc = XCreateGC(xfi->display, xfi->drawable, 0, NULL);
|
||||
XPutImage(xfi->display, bitmap, gc, image, 0, 0, 0, 0, width, height);
|
||||
XFree(image);
|
||||
|
||||
if (cdata != data)
|
||||
xfree(cdata);
|
||||
|
||||
@ -489,6 +495,11 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
|
||||
{
|
||||
printf("DrawNineGrid\n");
|
||||
}
|
||||
|
||||
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
|
||||
{
|
||||
uint32 color;
|
||||
@ -542,7 +553,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
xf_set_rop2(xfi, polyline->bRop2);
|
||||
color = freerdp_color_convert_rgb(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
color = freerdp_color_convert_var(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, color);
|
||||
@ -620,7 +631,242 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
|
||||
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
rdpBrush* brush;
|
||||
xfBitmap* bitmap;
|
||||
uint32 foreColor;
|
||||
uint32 backColor;
|
||||
Pixmap pattern = 0;
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
brush = &mem3blt->brush;
|
||||
bitmap = (xfBitmap*) mem3blt->bitmap;
|
||||
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
|
||||
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
backColor = freerdp_color_convert_rgb(mem3blt->backColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
if (brush->style == GDI_BS_PATTERN)
|
||||
{
|
||||
if (brush->bpp > 1)
|
||||
{
|
||||
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
|
||||
XSetTile(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
|
||||
XSetStipple(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
}
|
||||
}
|
||||
else if (brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Mem3Blt unimplemented brush style:%d\n", brush->style);
|
||||
}
|
||||
|
||||
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc,
|
||||
mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
|
||||
mem3blt->nLeftRect, mem3blt->nTopRect);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
if (xfi->remote_app != true)
|
||||
{
|
||||
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc,
|
||||
mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
|
||||
mem3blt->nLeftRect, mem3blt->nTopRect);
|
||||
}
|
||||
|
||||
gdi_InvalidateRegion(xfi->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight);
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
|
||||
|
||||
if (pattern != 0)
|
||||
XFreePixmap(xfi->display, pattern);
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
}
|
||||
|
||||
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
int i, npoints;
|
||||
XPoint* points;
|
||||
uint32 brush_color;
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
xf_set_rop2(xfi, polygon_sc->bRop2);
|
||||
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
npoints = polygon_sc->numPoints + 1;
|
||||
points = xmalloc(sizeof(XPoint) * npoints);
|
||||
|
||||
points[0].x = polygon_sc->xStart;
|
||||
points[0].y = polygon_sc->yStart;
|
||||
|
||||
for (i = 0; i < polygon_sc->numPoints; i++)
|
||||
{
|
||||
points[i + 1].x = polygon_sc->points[i].x;
|
||||
points[i + 1].y = polygon_sc->points[i].y;
|
||||
}
|
||||
|
||||
switch (polygon_sc->fillMode)
|
||||
{
|
||||
case 1: /* alternate */
|
||||
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
|
||||
break;
|
||||
|
||||
case 2: /* winding */
|
||||
XSetFillRule(xfi->display, xfi->gc, WindingRule);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
|
||||
break;
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, brush_color);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
xfree(points);
|
||||
}
|
||||
|
||||
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
int i, npoints;
|
||||
XPoint* points;
|
||||
Pixmap pattern;
|
||||
rdpBrush* brush;
|
||||
uint32 foreColor;
|
||||
uint32 backColor;
|
||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||
|
||||
brush = &(polygon_cb->brush);
|
||||
xf_set_rop2(xfi, polygon_cb->bRop2);
|
||||
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
npoints = polygon_cb->numPoints + 1;
|
||||
points = xmalloc(sizeof(XPoint) * npoints);
|
||||
|
||||
points[0].x = polygon_cb->xStart;
|
||||
points[0].y = polygon_cb->yStart;
|
||||
|
||||
for (i = 0; i < polygon_cb->numPoints; i++)
|
||||
{
|
||||
points[i + 1].x = polygon_cb->points[i].x;
|
||||
points[i + 1].y = polygon_cb->points[i].y;
|
||||
}
|
||||
|
||||
switch (polygon_cb->fillMode)
|
||||
{
|
||||
case 1: /* alternate */
|
||||
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
|
||||
break;
|
||||
|
||||
case 2: /* winding */
|
||||
XSetFillRule(xfi->display, xfi->gc, WindingRule);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (brush->style == GDI_BS_PATTERN)
|
||||
{
|
||||
if (brush->bpp > 1)
|
||||
{
|
||||
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
|
||||
XSetTile(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
|
||||
XFreePixmap(xfi->display, pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||
|
||||
if (polygon_cb->backMode == BACKMODE_TRANSPARENT)
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
|
||||
else if (polygon_cb->backMode == BACKMODE_OPAQUE)
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
|
||||
|
||||
XSetStipple(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
|
||||
points, npoints, Complex, CoordModePrevious);
|
||||
}
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
|
||||
XFreePixmap(xfi->display, pattern);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("PolygonCB unimplemented brush style:%d\n", brush->style);
|
||||
}
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
xfree(points);
|
||||
}
|
||||
|
||||
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
{
|
||||
printf("EllipseSC\n");
|
||||
}
|
||||
|
||||
void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
|
||||
{
|
||||
printf("EllipseCB\n");
|
||||
}
|
||||
|
||||
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
|
||||
@ -777,10 +1023,10 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
primary->GlyphIndex = NULL;
|
||||
primary->FastIndex = NULL;
|
||||
primary->FastGlyph = NULL;
|
||||
primary->PolygonSC = NULL;
|
||||
primary->PolygonCB = NULL;
|
||||
primary->EllipseSC = NULL;
|
||||
primary->EllipseCB = NULL;
|
||||
primary->PolygonSC = xf_gdi_polygon_sc;
|
||||
primary->PolygonCB = xf_gdi_polygon_cb;
|
||||
primary->EllipseSC = xf_gdi_ellipse_sc;
|
||||
primary->EllipseCB = xf_gdi_ellipse_cb;
|
||||
|
||||
update->SurfaceBits = xf_gdi_surface_bits;
|
||||
update->SurfaceFrameMarker = xf_gdi_surface_frame_marker;
|
||||
|
@ -495,15 +495,19 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
settings->order_support[NEG_LINETO_INDEX] = true;
|
||||
settings->order_support[NEG_POLYLINE_INDEX] = true;
|
||||
settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache;
|
||||
settings->order_support[NEG_MEM3BLT_INDEX] = false;
|
||||
|
||||
settings->order_support[NEG_MEM3BLT_INDEX] = (settings->sw_gdi) ? true : false;
|
||||
|
||||
settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache;
|
||||
settings->order_support[NEG_MEM3BLT_V2_INDEX] = false;
|
||||
settings->order_support[NEG_SAVEBITMAP_INDEX] = false;
|
||||
settings->order_support[NEG_GLYPH_INDEX_INDEX] = true;
|
||||
settings->order_support[NEG_FAST_INDEX_INDEX] = true;
|
||||
settings->order_support[NEG_FAST_GLYPH_INDEX] = true;
|
||||
settings->order_support[NEG_POLYGON_SC_INDEX] = false;
|
||||
settings->order_support[NEG_POLYGON_CB_INDEX] = false;
|
||||
|
||||
settings->order_support[NEG_POLYGON_SC_INDEX] = (settings->sw_gdi) ? false : true;
|
||||
settings->order_support[NEG_POLYGON_CB_INDEX] = (settings->sw_gdi) ? false : true;
|
||||
|
||||
settings->order_support[NEG_ELLIPSE_SC_INDEX] = false;
|
||||
settings->order_support[NEG_ELLIPSE_CB_INDEX] = false;
|
||||
|
||||
|
@ -517,7 +517,7 @@ void test_read_polygon_cb_order(void)
|
||||
CU_ASSERT(polygon_cb.brush.x == 4);
|
||||
CU_ASSERT(polygon_cb.brush.y == 3);
|
||||
CU_ASSERT(polygon_cb.brush.style == 0x81);
|
||||
CU_ASSERT(polygon_cb.nDeltaEntries == 3);
|
||||
CU_ASSERT(polygon_cb.numPoints == 3);
|
||||
CU_ASSERT(polygon_cb.cbData == 5);
|
||||
|
||||
CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1));
|
||||
|
4
include/freerdp/cache/brush.h
vendored
4
include/freerdp/cache/brush.h
vendored
@ -41,7 +41,9 @@ struct rdp_brush_cache
|
||||
{
|
||||
pPatBlt PatBlt; /* 0 */
|
||||
pCacheBrush CacheBrush; /* 1 */
|
||||
uint32 paddingA[16 - 2]; /* 2 */
|
||||
pPolygonSC PolygonSC; /* 2 */
|
||||
pPolygonCB PolygonCB; /* 3 */
|
||||
uint32 paddingA[16 - 4]; /* 4 */
|
||||
|
||||
uint32 maxEntries; /* 16 */
|
||||
uint32 maxMonoEntries; /* 17 */
|
||||
|
2
include/freerdp/cache/cache.h
vendored
2
include/freerdp/cache/cache.h
vendored
@ -29,6 +29,7 @@
|
||||
#include <freerdp/cache/brush.h>
|
||||
#include <freerdp/cache/pointer.h>
|
||||
#include <freerdp/cache/bitmap.h>
|
||||
#include <freerdp/cache/nine_grid.h>
|
||||
#include <freerdp/cache/offscreen.h>
|
||||
#include <freerdp/cache/palette.h>
|
||||
|
||||
@ -40,6 +41,7 @@ struct rdp_cache
|
||||
rdpBitmapCache* bitmap; /* 3 */
|
||||
rdpOffscreenCache* offscreen; /* 4 */
|
||||
rdpPaletteCache* palette; /* 5 */
|
||||
rdpNineGridCache* nine_grid; /* 6 */
|
||||
|
||||
/* internal */
|
||||
|
||||
|
63
include/freerdp/cache/nine_grid.h
vendored
Normal file
63
include/freerdp/cache/nine_grid.h
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* NineGrid Cache
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __NINE_GRID_CACHE_H
|
||||
#define __NINE_GRID_CACHE_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/update.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
typedef struct _NINE_GRID_ENTRY NINE_GRID_ENTRY;
|
||||
typedef struct rdp_nine_grid_cache rdpNineGridCache;
|
||||
|
||||
#include <freerdp/cache/cache.h>
|
||||
|
||||
struct _NINE_GRID_ENTRY
|
||||
{
|
||||
void* entry;
|
||||
};
|
||||
|
||||
struct rdp_nine_grid_cache
|
||||
{
|
||||
pDrawNineGrid DrawNineGrid; /* 0 */
|
||||
pMultiDrawNineGrid MultiDrawNineGrid; /* 1 */
|
||||
uint32 paddingA[16 - 2]; /* 2 */
|
||||
|
||||
uint32 maxEntries; /* 16 */
|
||||
uint32 maxSize; /* 17 */
|
||||
NINE_GRID_ENTRY* entries; /* 18 */
|
||||
uint32 paddingB[32 - 19]; /* 19 */
|
||||
|
||||
/* internal */
|
||||
|
||||
rdpSettings* settings;
|
||||
};
|
||||
|
||||
FREERDP_API void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index);
|
||||
FREERDP_API void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry);
|
||||
|
||||
FREERDP_API void nine_grid_cache_register_callbacks(rdpUpdate* update);
|
||||
|
||||
FREERDP_API rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings);
|
||||
FREERDP_API void nine_grid_cache_free(rdpNineGridCache* nine_grid);
|
||||
|
||||
#endif /* __NINE_GRID_CACHE_H */
|
@ -63,11 +63,26 @@
|
||||
#define GDI_BLACKNESS 0x00000042 /* D = 0 */
|
||||
#define GDI_WHITENESS 0x00FF0062 /* D = 1 */
|
||||
#define GDI_DSPDxax 0x00E20746 /* D = (S & P) | (~S & D) */
|
||||
#define GDI_PSDPxax 0x00B8074A /* D = (S & D) | (~S & P) */
|
||||
#define GDI_SPna 0x000C0324 /* D = S & ~P */
|
||||
#define GDI_DSna 0x00220326 /* D = D & ~S */
|
||||
#define GDI_DPa 0x00A000C9 /* D = D & P */
|
||||
#define GDI_PDxn 0x00A50065 /* D = D ^ ~P */
|
||||
|
||||
#define GDI_DPon 0x000500A9
|
||||
#define GDI_DPna 0x000A0329
|
||||
#define GDI_Pn 0x000F0001
|
||||
#define GDI_PDna 0x00500325
|
||||
#define GDI_DPan 0x005F00E9
|
||||
#define GDI_DSan 0x007700E6
|
||||
#define GDI_DSxn 0x00990066
|
||||
#define GDI_DPa 0x00A000C9
|
||||
#define GDI_D 0x00AA0029
|
||||
#define GDI_DPno 0x00AF0229
|
||||
#define GDI_SDno 0x00DD0228
|
||||
#define GDI_PDno 0x00F50225
|
||||
#define GDI_DPo 0x00FA0089
|
||||
|
||||
/* Brush Styles */
|
||||
#define GDI_BS_SOLID 0x00
|
||||
#define GDI_BS_NULL 0x01
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#define BACKMODE_TRANSPARENT 0x0001
|
||||
#define BACKMODE_OPAQUE 0x0002
|
||||
|
||||
struct rdp_bounds
|
||||
{
|
||||
sint32 left;
|
||||
@ -365,9 +368,9 @@ struct _POLYGON_SC_ORDER
|
||||
uint32 bRop2;
|
||||
uint32 fillMode;
|
||||
uint32 brushColor;
|
||||
uint32 nDeltaEntries;
|
||||
uint32 numPoints;
|
||||
uint32 cbData;
|
||||
uint8* codeDeltaList;
|
||||
DELTA_POINT* points;
|
||||
};
|
||||
typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER;
|
||||
|
||||
@ -376,13 +379,14 @@ struct _POLYGON_CB_ORDER
|
||||
sint32 xStart;
|
||||
sint32 yStart;
|
||||
uint32 bRop2;
|
||||
uint32 backMode;
|
||||
uint32 fillMode;
|
||||
uint32 backColor;
|
||||
uint32 foreColor;
|
||||
rdpBrush brush;
|
||||
uint32 nDeltaEntries;
|
||||
uint32 numPoints;
|
||||
uint32 cbData;
|
||||
uint8* codeDeltaList;
|
||||
DELTA_POINT* points;
|
||||
};
|
||||
typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER;
|
||||
|
||||
|
@ -21,6 +21,7 @@ set(FREERDP_CACHE_SRCS
|
||||
brush.c
|
||||
pointer.c
|
||||
bitmap.c
|
||||
nine_grid.c
|
||||
offscreen.c
|
||||
palette.c
|
||||
glyph.c
|
||||
|
@ -39,16 +39,27 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
|
||||
void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
uint8 style;
|
||||
rdpBitmap* bitmap;
|
||||
rdpCache* cache = context->cache;
|
||||
rdpBrush* brush = &mem3blt->brush;
|
||||
|
||||
if (mem3blt->cacheId == 0xFF)
|
||||
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (uint8) mem3blt->cacheId, mem3blt->cacheIndex);
|
||||
|
||||
style = brush->style;
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
{
|
||||
brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
|
||||
brush->style = 0x03;
|
||||
}
|
||||
|
||||
mem3blt->bitmap = bitmap;
|
||||
IFCALL(cache->bitmap->Mem3Blt, context, mem3blt);
|
||||
brush->style = style;
|
||||
}
|
||||
|
||||
void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap)
|
||||
|
@ -42,6 +42,30 @@ void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||
brush->style = style;
|
||||
}
|
||||
|
||||
void update_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
IFCALL(cache->brush->PolygonSC, context, polygon_sc);
|
||||
}
|
||||
|
||||
void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
uint8 style;
|
||||
rdpBrush* brush = &polygon_cb->brush;
|
||||
rdpCache* cache = context->cache;
|
||||
|
||||
style = brush->style;
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
{
|
||||
brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
|
||||
brush->style = 0x03;
|
||||
}
|
||||
|
||||
IFCALL(cache->brush->PolygonCB, context, polygon_cb);
|
||||
brush->style = style;
|
||||
}
|
||||
|
||||
void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
@ -127,8 +151,12 @@ void brush_cache_register_callbacks(rdpUpdate* update)
|
||||
rdpCache* cache = update->context->cache;
|
||||
|
||||
cache->brush->PatBlt = update->primary->PatBlt;
|
||||
cache->brush->PolygonSC = update->primary->PolygonSC;
|
||||
cache->brush->PolygonCB = update->primary->PolygonCB;
|
||||
|
||||
update->primary->PatBlt = update_gdi_patblt;
|
||||
update->primary->PolygonSC = update_gdi_polygon_sc;
|
||||
update->primary->PolygonCB = update_gdi_polygon_cb;
|
||||
update->secondary->CacheBrush = update_gdi_cache_brush;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ rdpCache* cache_new(rdpSettings* settings)
|
||||
cache->bitmap = bitmap_cache_new(settings);
|
||||
cache->offscreen = offscreen_cache_new(settings);
|
||||
cache->palette = palette_cache_new(settings);
|
||||
cache->nine_grid = nine_grid_cache_new(settings);
|
||||
}
|
||||
|
||||
return cache;
|
||||
@ -52,6 +53,7 @@ void cache_free(rdpCache* cache)
|
||||
bitmap_cache_free(cache->bitmap);
|
||||
offscreen_cache_free(cache->offscreen);
|
||||
palette_cache_free(cache->palette);
|
||||
nine_grid_cache_free(cache->nine_grid);
|
||||
xfree(cache);
|
||||
}
|
||||
}
|
||||
|
130
libfreerdp-cache/nine_grid.c
Normal file
130
libfreerdp-cache/nine_grid.c
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* NineGrid Cache
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/update.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/cache/nine_grid.h>
|
||||
|
||||
void update_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
IFCALL(cache->nine_grid->DrawNineGrid, context, draw_nine_grid);
|
||||
}
|
||||
|
||||
void update_gdi_multi_draw_nine_grid(rdpContext* context, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
IFCALL(cache->nine_grid->MultiDrawNineGrid, context, multi_draw_nine_grid);
|
||||
}
|
||||
|
||||
void nine_grid_cache_register_callbacks(rdpUpdate* update)
|
||||
{
|
||||
rdpCache* cache = update->context->cache;
|
||||
|
||||
cache->nine_grid->DrawNineGrid = update->primary->DrawNineGrid;
|
||||
cache->nine_grid->MultiDrawNineGrid = update->primary->MultiDrawNineGrid;
|
||||
|
||||
update->primary->DrawNineGrid = update_gdi_draw_nine_grid;
|
||||
update->primary->MultiDrawNineGrid = update_gdi_multi_draw_nine_grid;
|
||||
}
|
||||
|
||||
void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index)
|
||||
{
|
||||
void* entry;
|
||||
|
||||
if (index > nine_grid->maxEntries)
|
||||
{
|
||||
printf("invalid NineGrid index: 0x%04X\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = nine_grid->entries[index].entry;
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
printf("invalid NineGrid at index: 0x%04X\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry)
|
||||
{
|
||||
void* prevEntry;
|
||||
|
||||
if (index > nine_grid->maxEntries)
|
||||
{
|
||||
printf("invalid NineGrid index: 0x%04X\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
prevEntry = nine_grid->entries[index].entry;
|
||||
|
||||
if (prevEntry != NULL)
|
||||
xfree(prevEntry);
|
||||
|
||||
nine_grid->entries[index].entry = entry;
|
||||
}
|
||||
|
||||
rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings)
|
||||
{
|
||||
rdpNineGridCache* nine_grid;
|
||||
|
||||
nine_grid = (rdpNineGridCache*) xzalloc(sizeof(rdpNineGridCache));
|
||||
|
||||
if (nine_grid != NULL)
|
||||
{
|
||||
nine_grid->settings = settings;
|
||||
|
||||
nine_grid->maxSize = 2560;
|
||||
nine_grid->maxEntries = 256;
|
||||
|
||||
nine_grid->settings->draw_nine_grid_cache_size = nine_grid->maxSize;
|
||||
nine_grid->settings->draw_nine_grid_cache_entries = nine_grid->maxEntries;
|
||||
|
||||
nine_grid->entries = (NINE_GRID_ENTRY*) xzalloc(sizeof(NINE_GRID_ENTRY) * nine_grid->maxEntries);
|
||||
}
|
||||
|
||||
return nine_grid;
|
||||
}
|
||||
|
||||
void nine_grid_cache_free(rdpNineGridCache* nine_grid)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (nine_grid != NULL)
|
||||
{
|
||||
if (nine_grid->entries != NULL)
|
||||
{
|
||||
for (i = 0; i < (int) nine_grid->maxEntries; i++)
|
||||
{
|
||||
if (nine_grid->entries[i].entry != NULL)
|
||||
xfree(nine_grid->entries[i].entry);
|
||||
}
|
||||
|
||||
xfree(nine_grid->entries);
|
||||
}
|
||||
|
||||
xfree(nine_grid);
|
||||
}
|
||||
}
|
@ -1110,7 +1110,7 @@ void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* setti
|
||||
|
||||
header = rdp_capability_set_start(s);
|
||||
|
||||
drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT;
|
||||
drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
|
||||
|
||||
stream_write_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
|
||||
stream_write_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */
|
||||
@ -2026,6 +2026,12 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
|
||||
rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
|
||||
}
|
||||
|
||||
if (settings->draw_nine_grid)
|
||||
{
|
||||
numberCapabilities++;
|
||||
rdp_write_draw_nine_grid_cache_capability_set(s, settings);
|
||||
}
|
||||
|
||||
if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
|
||||
{
|
||||
if (settings->large_pointer)
|
||||
|
@ -1086,12 +1086,18 @@ void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_O
|
||||
update_read_color(s, &polygon_sc->brushColor);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_06)
|
||||
stream_read_uint8(s, polygon_sc->nDeltaEntries);
|
||||
stream_read_uint8(s, polygon_sc->numPoints);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_07)
|
||||
{
|
||||
stream_read_uint8(s, polygon_sc->cbData);
|
||||
stream_seek(s, polygon_sc->cbData);
|
||||
|
||||
if (polygon_sc->points == NULL)
|
||||
polygon_sc->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
else
|
||||
polygon_sc->points = (DELTA_POINT*) xrealloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints);
|
||||
|
||||
update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1118,13 +1124,22 @@ void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_O
|
||||
update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_12)
|
||||
stream_read_uint8(s, polygon_cb->nDeltaEntries);
|
||||
stream_read_uint8(s, polygon_cb->numPoints);
|
||||
|
||||
if (orderInfo->fieldFlags & ORDER_FIELD_13)
|
||||
{
|
||||
stream_read_uint8(s, polygon_cb->cbData);
|
||||
stream_seek(s, polygon_cb->cbData);
|
||||
|
||||
if (polygon_cb->points == NULL)
|
||||
polygon_cb->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
else
|
||||
polygon_cb->points = (DELTA_POINT*) xrealloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints);
|
||||
|
||||
update_read_delta_points(s, polygon_cb->points, polygon_cb->numPoints, polygon_cb->xStart, polygon_cb->yStart);
|
||||
}
|
||||
|
||||
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
|
||||
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
||||
}
|
||||
|
||||
void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
|
@ -407,6 +407,60 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int BitBlt_PSDPxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
uint16* srcp;
|
||||
uint16* dstp;
|
||||
uint16* patp;
|
||||
uint16 color16;
|
||||
|
||||
/* D = (S & D) | (~S & P) */
|
||||
|
||||
if (hdcDest->brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
|
||||
patp = (uint16*) &color16;
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
@ -721,6 +775,10 @@ int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh
|
||||
return BitBlt_DSPDxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_PSDPxax:
|
||||
return BitBlt_PSDPxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_NOTSRCCOPY:
|
||||
return BitBlt_NOTSRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
@ -385,48 +385,115 @@ static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
|
||||
static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
uint8* srcp;
|
||||
uint8* dstp;
|
||||
uint8* patp;
|
||||
uint32* srcp;
|
||||
uint32* dstp;
|
||||
uint32* patp;
|
||||
uint8* srcp8;
|
||||
uint32 src32;
|
||||
uint32 color32;
|
||||
HGDI_BITMAP hSrcBmp;
|
||||
|
||||
/* D = (S & P) | (~S & D) */
|
||||
/* DSPDxax, used to draw glyphs */
|
||||
|
||||
color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor);
|
||||
|
||||
patp = (uint32*) &color32;
|
||||
hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
|
||||
srcp = hSrcBmp->data;
|
||||
|
||||
if (hdcSrc->bytesPerPixel != 1)
|
||||
if (hdcSrc->bytesPerPixel == 1)
|
||||
{
|
||||
printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
/* DSPDxax, used to draw glyphs */
|
||||
|
||||
if (dstp != 0)
|
||||
srcp = (uint32*) & src32;
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
srcp8 = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
patp = (uint8*) &color32;
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
*srcp = ((*srcp8) | (*srcp8 << 8) | (*srcp8 << 16) | (*srcp8 << 24));
|
||||
|
||||
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
|
||||
dstp++;
|
||||
patp++;
|
||||
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
|
||||
dstp++;
|
||||
|
||||
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
|
||||
dstp++;
|
||||
patp++;
|
||||
srcp8++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
|
||||
dstp += 2;
|
||||
srcp++;
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
uint32* srcp;
|
||||
uint32* dstp;
|
||||
uint32* patp;
|
||||
uint32 color32;
|
||||
|
||||
/* D = (S & D) | (~S & P) */
|
||||
|
||||
if (hdcDest->brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color);
|
||||
patp = (uint32*) &color32;
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y);
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -750,6 +817,10 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh
|
||||
return BitBlt_DSPDxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_PSDPxax:
|
||||
return BitBlt_PSDPxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_NOTSRCCOPY:
|
||||
return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
@ -33,6 +33,12 @@
|
||||
|
||||
#include <freerdp/gdi/8bpp.h>
|
||||
|
||||
uint8 gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color)
|
||||
{
|
||||
/* TODO: Implement 8bpp gdi_get_color_8bpp() */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
|
||||
{
|
||||
/* TODO: Implement 8bpp FillRect() */
|
||||
@ -310,6 +316,60 @@ static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int BitBlt_PSDPxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
uint8* srcp;
|
||||
uint8* dstp;
|
||||
uint8* patp;
|
||||
uint8 color8;
|
||||
|
||||
/* D = (S & D) | (~S & P) */
|
||||
|
||||
if (hdcDest->brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
color8 = gdi_get_color_8bpp(hdcDest, hdcDest->brush->color);
|
||||
patp = (uint8*) &color8;
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
|
||||
dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
|
||||
|
||||
if (dstp != 0)
|
||||
{
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
patp = (uint8*) gdi_get_brush_pointer(hdcDest, x, y);
|
||||
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
|
||||
srcp++;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
|
||||
{
|
||||
int x, y;
|
||||
@ -631,6 +691,10 @@ int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight
|
||||
return BitBlt_DSPDxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_PSDPxax:
|
||||
return BitBlt_PSDPxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
||||
case GDI_NOTSRCCOPY:
|
||||
return BitBlt_NOTSRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
|
||||
break;
|
||||
|
@ -628,7 +628,35 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
|
||||
void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
printf("Mem3Blt\n");
|
||||
rdpBrush* brush;
|
||||
uint32 foreColor;
|
||||
uint32 backColor;
|
||||
gdiBitmap* bitmap;
|
||||
HGDI_BRUSH originalBrush;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
brush = &mem3blt->brush;
|
||||
bitmap = (gdiBitmap*) mem3blt->bitmap;
|
||||
|
||||
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
|
||||
if (brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
originalBrush = gdi->drawing->hdc->brush;
|
||||
gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor);
|
||||
|
||||
gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
|
||||
mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
|
||||
mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop));
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
|
||||
gdi->drawing->hdc->brush = originalBrush;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Mem3Blt unimplemented brush style:%d\n", brush->style);
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
|
Loading…
Reference in New Issue
Block a user