Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2012-02-13 17:51:56 -05:00
commit 06330a7cb3
19 changed files with 811 additions and 61 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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 */

View File

@ -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
View 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 */

View File

@ -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

View File

@ -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;

View File

@ -21,6 +21,7 @@ set(FREERDP_CACHE_SRCS
brush.c
pointer.c
bitmap.c
nine_grid.c
offscreen.c
palette.c
glyph.c

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}
}

View 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);
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)