--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Library
+ *
+ * Copyright 2010-2011 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef __GDI_H
+#define __GDI_H
+
+#include "color.h"
+#include <freerdp/rfx.h>
+#include <freerdp/freerdp.h>
+#include <freerdp/utils/debug.h>
+
+/* For more information, see [MS-RDPEGDI] */
+
+/* Binary Raster Operations (ROP2) */
+#define GDI_R2_BLACK 0x01 /* D = 0 */
+#define GDI_R2_NOTMERGEPEN 0x02 /* D = ~(D | P) */
+#define GDI_R2_MASKNOTPEN 0x03 /* D = D & ~P */
+#define GDI_R2_NOTCOPYPEN 0x04 /* D = ~P */
+#define GDI_R2_MASKPENNOT 0x05 /* D = P & ~D */
+#define GDI_R2_NOT 0x06 /* D = ~D */
+#define GDI_R2_XORPEN 0x07 /* D = D ^ P */
+#define GDI_R2_NOTMASKPEN 0x08 /* D = ~(D & P) */
+#define GDI_R2_MASKPEN 0x09 /* D = D & P */
+#define GDI_R2_NOTXORPEN 0x0A /* D = ~(D ^ P) */
+#define GDI_R2_NOP 0x0B /* D = D */
+#define GDI_R2_MERGENOTPEN 0x0C /* D = D | ~P */
+#define GDI_R2_COPYPEN 0x0D /* D = P */
+#define GDI_R2_MERGEPENNOT 0x0E /* D = P | ~D */
+#define GDI_R2_MERGEPEN 0x0F /* D = P | D */
+#define GDI_R2_WHITE 0x10 /* D = 1 */
+
+/* Ternary Raster Operations (ROP3) */
+#define GDI_SRCCOPY 0x00CC0020 /* D = S */
+#define GDI_SRCPAINT 0x00EE0086 /* D = S | D */
+#define GDI_SRCAND 0x008800C6 /* D = S & D */
+#define GDI_SRCINVERT 0x00660046 /* D = S ^ D */
+#define GDI_SRCERASE 0x00440328 /* D = S & ~D */
+#define GDI_NOTSRCCOPY 0x00330008 /* D = ~S */
+#define GDI_NOTSRCERASE 0x001100A6 /* D = ~S & ~D */
+#define GDI_MERGECOPY 0x00C000CA /* D = S & P */
+#define GDI_MERGEPAINT 0x00BB0226 /* D = ~S | D */
+#define GDI_PATCOPY 0x00F00021 /* D = P */
+#define GDI_PATPAINT 0x00FB0A09 /* D = D | (P | ~S) */
+#define GDI_PATINVERT 0x005A0049 /* D = P ^ D */
+#define GDI_DSTINVERT 0x00550009 /* D = ~D */
+#define GDI_BLACKNESS 0x00000042 /* D = 0 */
+#define GDI_WHITENESS 0x00FF0062 /* D = 1 */
+#define GDI_DSPDxax 0x00E20746 /* D = (S & P) | (~S & D) */
+#define GDI_SPna 0x000C0324 /* D = S & ~P */
+#define GDI_DSna 0x00220326 /* D = D & ~S */
+
+/* Brush Styles */
+#define GDI_BS_SOLID 0x00
+#define GDI_BS_NULL 0x01
+#define GDI_BS_HATCHED 0x02
+#define GDI_BS_PATTERN 0x03
+
+/* Hatch Patterns */
+#define GDI_HS_HORIZONTAL 0x00
+#define GDI_HS_VERTICAL 0x01
+#define GDI_HS_FDIAGONAL 0x02
+#define GDI_HS_BDIAGONAL 0x03
+#define GDI_HS_CROSS 0x04
+#define GDI_HS_DIAGCROSS 0x05
+
+/* Pen Styles */
+#define GDI_PS_SOLID 0x00
+#define GDI_PS_DASH 0x01
+#define GDI_PS_NULL 0x05
+
+/* Background Modes */
+#define GDI_OPAQUE 0x00000001
+#define GDI_TRANSPARENT 0x00000002
+
+/* GDI Object Types */
+#define GDIOBJECT_BITMAP 0x00
+#define GDIOBJECT_PEN 0x01
+#define GDIOBJECT_PALETTE 0x02
+#define GDIOBJECT_BRUSH 0x03
+#define GDIOBJECT_RECT 0x04
+#define GDIOBJECT_REGION 0x04
+
+struct _GDIOBJECT
+{
+ uint8 objectType;
+};
+typedef struct _GDIOBJECT GDIOBJECT;
+typedef GDIOBJECT* HGDIOBJECT;
+
+/* RGB encoded as 0x00BBGGRR */
+typedef unsigned int GDI_COLOR;
+typedef GDI_COLOR* LPGDI_COLOR;
+
+struct _GDI_RECT
+{
+ uint8 objectType;
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
+typedef struct _GDI_RECT GDI_RECT;
+typedef GDI_RECT* HGDI_RECT;
+
+struct _GDI_RGN
+{
+ uint8 objectType;
+ int x; /* left */
+ int y; /* top */
+ int w; /* width */
+ int h; /* height */
+ int null; /* null region */
+};
+typedef struct _GDI_RGN GDI_RGN;
+typedef GDI_RGN* HGDI_RGN;
+
+struct _GDI_BITMAP
+{
+ uint8 objectType;
+ int bytesPerPixel;
+ int bitsPerPixel;
+ int width;
+ int height;
+ int scanline;
+ uint8* data;
+};
+typedef struct _GDI_BITMAP GDI_BITMAP;
+typedef GDI_BITMAP* HGDI_BITMAP;
+
+struct _GDI_PEN
+{
+ uint8 objectType;
+ int style;
+ int width;
+ int posX;
+ int posY;
+ GDI_COLOR color;
+};
+typedef struct _GDI_PEN GDI_PEN;
+typedef GDI_PEN* HGDI_PEN;
+
+struct _GDI_PALETTEENTRY
+{
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+};
+typedef struct _GDI_PALETTEENTRY GDI_PALETTEENTRY;
+
+struct _GDI_PALETTE
+{
+ uint16 count;
+ GDI_PALETTEENTRY *entries;
+};
+typedef struct _GDI_PALETTE GDI_PALETTE;
+typedef GDI_PALETTE* HGDI_PALETTE;
+
+struct _GDI_POINT
+{
+ int x;
+ int y;
+};
+typedef struct _GDI_POINT GDI_POINT;
+typedef GDI_POINT* HGDI_POINT;
+
+struct _GDI_BRUSH
+{
+ uint8 objectType;
+ int style;
+ HGDI_BITMAP pattern;
+ GDI_COLOR color;
+};
+typedef struct _GDI_BRUSH GDI_BRUSH;
+typedef GDI_BRUSH* HGDI_BRUSH;
+
+struct _GDI_WND
+{
+ HGDI_RGN invalid;
+};
+typedef struct _GDI_WND GDI_WND;
+typedef GDI_WND* HGDI_WND;
+
+struct _GDI_DC
+{
+ HGDIOBJECT selectedObject;
+ int bytesPerPixel;
+ int bitsPerPixel;
+ GDI_COLOR bkColor;
+ GDI_COLOR textColor;
+ HGDI_BRUSH brush;
+ HGDI_RGN clip;
+ HGDI_PEN pen;
+ HGDI_WND hwnd;
+ int drawMode;
+ int bkMode;
+ int alpha;
+ int invert;
+ int rgb555;
+};
+typedef struct _GDI_DC GDI_DC;
+typedef GDI_DC* HGDI_DC;
+
+struct _GDI_IMAGE
+{
+ HGDI_DC hdc;
+ HGDI_BITMAP bitmap;
+ HGDI_BITMAP org_bitmap;
+};
+typedef struct _GDI_IMAGE GDI_IMAGE;
+typedef GDI_IMAGE* HGDI_IMAGE;
+
+struct _GDI
+{
+ int width;
+ int height;
+ int dstBpp;
+ int srcBpp;
+ int cursor_x;
+ int cursor_y;
+ int bytesPerPixel;
+
+ HGDI_DC hdc;
+ HCLRCONV clrconv;
+ GDI_IMAGE *primary;
+ GDI_IMAGE *drawing;
+ uint8* primary_buffer;
+ GDI_COLOR textColor;
+ void * rfx_context;
+ GDI_IMAGE *tile;
+};
+typedef struct _GDI GDI;
+
+uint32 gdi_rop3_code(uint8 code);
+void gdi_copy_mem(uint8 *d, uint8 *s, int n);
+void gdi_copy_memb(uint8 *d, uint8 *s, int n);
+uint8* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y);
+uint8* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y);
+int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width);
+int gdi_init(rdpInst * inst, uint32 flags);
+GDI_IMAGE* gdi_bitmap_new(GDI *gdi, int width, int height, int bpp, uint8* data);
+void gdi_bitmap_free(GDI_IMAGE *gdi_bmp);
+void gdi_free(rdpInst* inst);
+
+#define SET_GDI(_inst, _gdi) (_inst)->param2 = _gdi
+#define GET_GDI(_inst) ((GDI*) ((_inst)->param2))
+
+#ifdef WITH_DEBUG_GDI
+#define DEBUG_GDI(fmt, ...) DEBUG_CLASS(GDI, fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_GDI(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#endif
+
+#endif /* __GDI_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 16bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "color.h"
+#include "gdi_pen.h"
+#include "gdi_bitmap.h"
+#include "gdi_region.h"
+#include "gdi_clipping.h"
+#include "gdi_drawing.h"
+
+#include "gdi_16bpp.h"
+
+uint16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color)
+{
+ uint8 r, g, b;
+ uint16 color16;
+
+ GetRGB32(r, g, b, color);
+
+ if(hdc->rgb555)
+ {
+ if (hdc->invert)
+ {
+ color16 = BGR15(r, g, b);
+ }
+ else
+ {
+ color16 = RGB15(r, g, b);
+ }
+ }
+ else
+ {
+ if (hdc->invert)
+ {
+ color16 = BGR16(r, g, b);
+ }
+ else
+ {
+ color16 = RGB16(r, g, b);
+ }
+ }
+
+ return color16;
+}
+
+int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
+{
+ int x, y;
+ uint16 *dstp;
+ int nXDest, nYDest;
+ int nWidth, nHeight;
+
+ uint16 color16;
+
+ gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
+
+ if (gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+
+ color16 = gdi_get_color_16bpp(hdc, hbr->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = (uint16*) gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = color16;
+ dstp++;
+ }
+ }
+ }
+
+ gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight);
+ return 0;
+}
+
+static int BitBlt_BLACKNESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0, nWidth * hdcDest->bytesPerPixel);
+ }
+
+ return 0;
+}
+
+static int BitBlt_WHITENESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel);
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
+{
+ int y;
+ uint8 *srcp;
+ uint8 *dstp;
+
+ if ((hdcDest->selectedObject != hdcSrc->selectedObject) ||
+ gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 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);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+
+ return 0;
+ }
+
+ if (nYSrc < nYDest)
+ {
+ /* copy down (bottom to top) */
+ for (y = nHeight - 1; y >= 0; y--)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else if (nYSrc > nYDest || nXSrc > nXDest)
+ {
+ /* copy up or left (top top bottom) */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else
+ {
+ /* copy straight right */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_memb(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCCOPY_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSTINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*dstp);
+ dstp++;
+
+ *dstp = ~(*dstp);
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCERASE_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = *srcp & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCERASE_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCINVERT_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp ^= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp ^= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCAND_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp &= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp &= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCPAINT_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp |= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp |= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSPDxax_16bpp(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;
+ uint16 color16;
+ HGDI_BITMAP hSrcBmp;
+
+ /* D = (S & P) | (~S & D) */
+ /* DSPDxax, used to draw glyphs */
+
+ color16 = gdi_get_color_16bpp(hdcDest, hdcDest->textColor);
+
+ hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
+ srcp = hSrcBmp->data;
+
+ 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);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = (uint8*) &color16;
+
+ *dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
+ dstp++;
+ patp++;
+
+ *dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
+ dstp++;
+ patp++;
+ srcp++;
+ }
+ }
+ }
+
+ 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;
+ uint8 *srcp;
+ uint8 *dstp;
+ uint8 *patp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & ~(*patp);
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*patp);
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSna_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & (*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & (*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static int BitBlt_MERGECOPY_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & *patp;
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & *patp;
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_MERGEPAINT_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) | *dstp;
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) | *dstp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint16 color16;
+ uint16 *dstp16;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp16 = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp16 != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp16 = color16;
+ dstp16++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp;
+ patp++;
+ dstp++;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint16 color16;
+ uint16 *dstp16;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp16 = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp16 != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp16 ^= color16;
+ dstp16++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp ^ *dstp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp ^ *dstp;
+ patp++;
+ dstp++;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATPAINT_16bpp(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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
+{
+ if (hdcSrc != NULL)
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
+ return 0;
+ }
+ else
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+ }
+
+ gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCCOPY:
+ return BitBlt_SRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SPna:
+ return BitBlt_SPna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSna:
+ return BitBlt_DSna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSPDxax:
+ return BitBlt_DSPDxax_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;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCERASE:
+ return BitBlt_SRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_NOTSRCERASE:
+ return BitBlt_NOTSRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCINVERT:
+ return BitBlt_SRCINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCAND:
+ return BitBlt_SRCAND_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCPAINT:
+ return BitBlt_SRCPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGECOPY:
+ return BitBlt_MERGECOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGEPAINT:
+ return BitBlt_MERGEPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATPAINT:
+ return BitBlt_PATPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+ }
+
+ printf("BitBlt: unknown rop: 0x%08X\n", rop);
+ return 1;
+}
+
+int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
+{
+ if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+
+ gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+ }
+
+ printf("PatBlt: unknown rop: 0x%08X", rop);
+ return 1;
+}
+
+void SetPixel_BLACK_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = 0 */
+ *pixel = 0;
+}
+
+void SetPixel_NOTMERGEPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = ~(D | P) */
+ *pixel = ~(*pixel | *pen);
+}
+
+void SetPixel_MASKNOTPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = D & ~P */
+ *pixel &= ~(*pen);
+}
+
+void SetPixel_NOTCOPYPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = ~P */
+ *pixel = ~(*pen);
+}
+
+void SetPixel_MASKPENNOT_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = P & ~D */
+ *pixel = *pen & ~*pixel;
+}
+
+void SetPixel_NOT_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = ~D */
+ *pixel = ~(*pixel);
+}
+
+void SetPixel_XORPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = D ^ P */
+ *pixel = *pixel ^ *pen;
+}
+
+void SetPixel_NOTMASKPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = ~(D & P) */
+ *pixel = ~(*pixel & *pen);
+}
+
+void SetPixel_MASKPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = D & P */
+ *pixel &= *pen;
+}
+
+void SetPixel_NOTXORPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = ~(D ^ P) */
+ *pixel = ~(*pixel ^ *pen);
+}
+
+void SetPixel_NOP_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = D */
+}
+
+void SetPixel_MERGENOTPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = D | ~P */
+ *pixel |= ~(*pen);
+}
+
+void SetPixel_COPYPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = P */
+ *pixel = *pen;
+}
+
+void SetPixel_MERGEPENNOT_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = P | ~D */
+ *pixel = *pen | ~(*pixel);
+}
+
+void SetPixel_MERGEPEN_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = P | D */
+ *pixel |= *pen;
+}
+
+void SetPixel_WHITE_16bpp(uint16 *pixel, uint16 *pen)
+{
+ /* D = 1 */
+ *pixel = 0xFFFF;
+}
+
+pSetPixel16_ROP2 SetPixel16_ROP2_[16] =
+{
+ SetPixel_BLACK_16bpp,
+ SetPixel_NOTMERGEPEN_16bpp,
+ SetPixel_MASKNOTPEN_16bpp,
+ SetPixel_NOTCOPYPEN_16bpp,
+ SetPixel_MASKPENNOT_16bpp,
+ SetPixel_NOT_16bpp,
+ SetPixel_XORPEN_16bpp,
+ SetPixel_NOTMASKPEN_16bpp,
+ SetPixel_MASKPEN_16bpp,
+ SetPixel_NOTXORPEN_16bpp,
+ SetPixel_NOP_16bpp,
+ SetPixel_MERGENOTPEN_16bpp,
+ SetPixel_COPYPEN_16bpp,
+ SetPixel_MERGEPENNOT_16bpp,
+ SetPixel_MERGEPEN_16bpp,
+ SetPixel_WHITE_16bpp
+};
+
+int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd)
+{
+ int x, y;
+ int x1, y1;
+ int x2, y2;
+ int e, e2;
+ int dx, dy;
+ int sx, sy;
+ HGDI_BITMAP bmp;
+ int bx1, by1;
+ int bx2, by2;
+
+ int irop2;
+ uint16 pen;
+ uint16 *pixel;
+
+ x1 = hdc->pen->posX;
+ y1 = hdc->pen->posY;
+ x2 = nXEnd;
+ y2 = nYEnd;
+
+ dx = (x1 > x2) ? x1 - x2 : x2 - x1;
+ dy = (y1 > y2) ? y1 - y2 : y2 - y1;
+
+ sx = (x1 < x2) ? 1 : -1;
+ sy = (y1 < y2) ? 1 : -1;
+
+ e = dx - dy;
+
+ x = x1;
+ y = y1;
+
+ irop2 = gdi_GetROP2(hdc) - 1;
+ bmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (hdc->clip->null)
+ {
+ bx1 = (x1 < x2) ? x1 : x2;
+ by1 = (y1 < y2) ? y1 : y2;
+ bx2 = (x1 > x2) ? x1 : x2;
+ by2 = (y1 > y2) ? y1 : y2;
+ }
+ else
+ {
+ bx1 = hdc->clip->x;
+ by1 = hdc->clip->y;
+ bx2 = bx1 + hdc->clip->w - 1;
+ by2 = by1 + hdc->clip->h - 1;
+ }
+
+ pen = gdi_GetPenColor_16bpp(hdc->pen);
+
+ while (1)
+ {
+ if (!(x == x2 && y == y2))
+ {
+ if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2))
+ {
+ pixel = gdi_GetPointer_16bpp(bmp, x, y);
+ SetPixel16_ROP2_[irop2](pixel, &pen);
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ e2 = 2 * e;
+
+ if (e2 > -dy)
+ {
+ e -= dy;
+ x += sx;
+ }
+
+ if (e2 < dx)
+ {
+ e += dx;
+ y += sy;
+ }
+ }
+
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 16bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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/freerdp.h>
+#include "gdi.h"
+
+typedef void (*pSetPixel16_ROP2)(uint16 *pixel, uint16 *pen);
+
+int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
+int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop);
+int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
+int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 32bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "color.h"
+#include "gdi_pen.h"
+#include "gdi_bitmap.h"
+#include "gdi_region.h"
+#include "gdi_clipping.h"
+#include "gdi_drawing.h"
+
+#include "gdi_32bpp.h"
+
+uint32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color)
+{
+ uint32 color32;
+ uint8 a, r, g, b;
+
+ a = 0xFF;
+ GetRGB32(r, g, b, color);
+
+ if (hdc->invert)
+ {
+ color32 = ABGR32(a, r, g, b);
+ }
+ else
+ {
+ color32 = ARGB32(a, r, g, b);
+ }
+
+ return color32;
+}
+
+int FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
+{
+ int x, y;
+ uint32 *dstp;
+ uint32 color32;
+ int nXDest, nYDest;
+ int nWidth, nHeight;
+
+ gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
+
+ if (gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+
+ color32 = gdi_get_color_32bpp(hdc, hbr->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = (uint32*) gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = color32;
+ dstp++;
+ }
+ }
+ }
+
+ gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight);
+ return 0;
+}
+
+static int BitBlt_BLACKNESS_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ if (hdcDest->alpha)
+ {
+ int x, y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = 0;
+ dstp++;
+
+ *dstp = 0;
+ dstp++;
+
+ *dstp = 0;
+ dstp++;
+
+ *dstp = 0xFF;
+ dstp++;
+ }
+ }
+ }
+ }
+ else
+ {
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_WHITENESS_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel);
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
+{
+ int y;
+ uint8 *srcp;
+ uint8 *dstp;
+
+ if ((hdcDest->selectedObject != hdcSrc->selectedObject) ||
+ gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 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);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+
+ return 0;
+ }
+
+ if (nYSrc < nYDest)
+ {
+ /* copy down (bottom to top) */
+ for (y = nHeight - 1; y >= 0; y--)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else if (nYSrc > nYDest || nXSrc > nXDest)
+ {
+ /* copy up or left (top top bottom) */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else
+ {
+ /* copy straight right */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_memb(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCCOPY_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp);
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSTINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*dstp);
+ dstp++;
+
+ *dstp = ~(*dstp);
+ dstp++;
+
+ *dstp = ~(*dstp);
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCERASE_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = *srcp & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*dstp);
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCERASE_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCINVERT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp ^= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp ^= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp ^= *srcp;
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCAND_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp &= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp &= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp &= *srcp;
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp |= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp |= *srcp;
+ srcp++;
+ dstp++;
+
+ *dstp |= *srcp;
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+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 color32;
+ HGDI_BITMAP hSrcBmp;
+
+ /* D = (S & P) | (~S & D) */
+ /* DSPDxax, used to draw glyphs */
+
+ color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor);
+
+ hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
+ srcp = hSrcBmp->data;
+
+ 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);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = (uint8*) &color32;
+
+ *dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
+ dstp++;
+ patp++;
+
+ *dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
+ dstp++;
+ patp++;
+
+ *dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
+ dstp += 2;
+ srcp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SPna_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & ~(*patp);
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*patp);
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & ~(*patp);
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSna_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & (*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & (*dstp);
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) & (*dstp);
+ srcp += 2;
+ dstp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static int BitBlt_MERGECOPY_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & *patp;
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & *patp;
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *srcp & *patp;
+ dstp += 2;
+ srcp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_MERGEPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) | *dstp;
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) | *dstp;
+ srcp++;
+ dstp++;
+
+ *dstp = ~(*srcp) | *dstp;
+ dstp += 2;
+ srcp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint32 color32;
+ uint32 *dstp32;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp32 = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp32 != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp32 = color32;
+ dstp32++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp;
+ dstp += 2;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint32 color32;
+ uint32 *dstp32;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color);
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp32 = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp32 != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp32 ^= color32;
+ dstp32++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp ^ *dstp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp ^ *dstp;
+ patp++;
+ dstp++;
+
+ *dstp = *patp ^ *dstp;
+ dstp += 2;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ patp++;
+ srcp++;
+ dstp++;
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ dstp += 2;
+ srcp += 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
+{
+ if (hdcSrc != NULL)
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
+ return 0;
+ }
+ else
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+ }
+
+ gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCCOPY:
+ return BitBlt_SRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SPna:
+ return BitBlt_SPna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSna:
+ return BitBlt_DSna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSPDxax:
+ return BitBlt_DSPDxax_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;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCERASE:
+ return BitBlt_SRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_NOTSRCERASE:
+ return BitBlt_NOTSRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCINVERT:
+ return BitBlt_SRCINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCAND:
+ return BitBlt_SRCAND_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCPAINT:
+ return BitBlt_SRCPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGECOPY:
+ return BitBlt_MERGECOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGEPAINT:
+ return BitBlt_MERGEPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATPAINT:
+ return BitBlt_PATPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+ }
+
+ printf("BitBlt: unknown rop: 0x%08X\n", rop);
+ return 1;
+}
+
+int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
+{
+ if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+
+ gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+ }
+
+ printf("PatBlt: unknown rop: 0x%08X", rop);
+ return 1;
+}
+
+void SetPixel_BLACK_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = 0 */
+ *pixel = 0;
+}
+
+void SetPixel_NOTMERGEPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = ~(D | P) */
+ *pixel = ~(*pixel | *pen);
+}
+
+void SetPixel_MASKNOTPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = D & ~P */
+ *pixel &= ~(*pen);
+}
+
+void SetPixel_NOTCOPYPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = ~P */
+ *pixel = ~(*pen);
+}
+
+void SetPixel_MASKPENNOT_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = P & ~D */
+ *pixel = *pen & ~*pixel;
+}
+
+void SetPixel_NOT_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = ~D */
+ *pixel = ~(*pixel);
+}
+
+void SetPixel_XORPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = D ^ P */
+ *pixel = *pixel ^ *pen;
+}
+
+void SetPixel_NOTMASKPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = ~(D & P) */
+ *pixel = ~(*pixel & *pen);
+}
+
+void SetPixel_MASKPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = D & P */
+ *pixel &= *pen;
+}
+
+void SetPixel_NOTXORPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = ~(D ^ P) */
+ *pixel = ~(*pixel ^ *pen);
+}
+
+void SetPixel_NOP_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = D */
+}
+
+void SetPixel_MERGENOTPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = D | ~P */
+ *pixel |= ~(*pen);
+}
+
+void SetPixel_COPYPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = P */
+ *pixel = *pen;
+}
+
+void SetPixel_MERGEPENNOT_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = P | ~D */
+ *pixel = *pen | ~(*pixel);
+}
+
+void SetPixel_MERGEPEN_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = P | D */
+ *pixel |= *pen;
+}
+
+void SetPixel_WHITE_32bpp(uint32 *pixel, uint32 *pen)
+{
+ /* D = 1 */
+ *pixel = 0xFFFFFF;
+}
+
+pSetPixel32_ROP2 SetPixel32_ROP2_[32] =
+{
+ SetPixel_BLACK_32bpp,
+ SetPixel_NOTMERGEPEN_32bpp,
+ SetPixel_MASKNOTPEN_32bpp,
+ SetPixel_NOTCOPYPEN_32bpp,
+ SetPixel_MASKPENNOT_32bpp,
+ SetPixel_NOT_32bpp,
+ SetPixel_XORPEN_32bpp,
+ SetPixel_NOTMASKPEN_32bpp,
+ SetPixel_MASKPEN_32bpp,
+ SetPixel_NOTXORPEN_32bpp,
+ SetPixel_NOP_32bpp,
+ SetPixel_MERGENOTPEN_32bpp,
+ SetPixel_COPYPEN_32bpp,
+ SetPixel_MERGEPENNOT_32bpp,
+ SetPixel_MERGEPEN_32bpp,
+ SetPixel_WHITE_32bpp
+};
+
+int LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd)
+{
+ int x, y;
+ int x1, y1;
+ int x2, y2;
+ int e, e2;
+ int dx, dy;
+ int sx, sy;
+ HGDI_BITMAP bmp;
+ int bx1, by1;
+ int bx2, by2;
+
+ int irop2;
+ uint32 pen;
+ uint32 *pixel;
+
+ x1 = hdc->pen->posX;
+ y1 = hdc->pen->posY;
+ x2 = nXEnd;
+ y2 = nYEnd;
+
+ dx = (x1 > x2) ? x1 - x2 : x2 - x1;
+ dy = (y1 > y2) ? y1 - y2 : y2 - y1;
+
+ sx = (x1 < x2) ? 1 : -1;
+ sy = (y1 < y2) ? 1 : -1;
+
+ e = dx - dy;
+
+ x = x1;
+ y = y1;
+
+ irop2 = gdi_GetROP2(hdc) - 1;
+ bmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (hdc->clip->null)
+ {
+ bx1 = (x1 < x2) ? x1 : x2;
+ by1 = (y1 < y2) ? y1 : y2;
+ bx2 = (x1 > x2) ? x1 : x2;
+ by2 = (y1 > y2) ? y1 : y2;
+ }
+ else
+ {
+ bx1 = hdc->clip->x;
+ by1 = hdc->clip->y;
+ bx2 = bx1 + hdc->clip->w - 1;
+ by2 = by1 + hdc->clip->h - 1;
+ }
+
+ pen = gdi_GetPenColor_32bpp(hdc->pen);
+
+ while (1)
+ {
+ if (!(x == x2 && y == y2))
+ {
+ if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2))
+ {
+ pixel = gdi_GetPointer_32bpp(bmp, x, y);
+ SetPixel32_ROP2_[irop2](pixel, &pen);
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ e2 = 2 * e;
+
+ if (e2 > -dy)
+ {
+ e -= dy;
+ x += sx;
+ }
+
+ if (e2 < dx)
+ {
+ e += dx;
+ y += sy;
+ }
+ }
+
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 32bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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/freerdp.h>
+#include "gdi.h"
+
+typedef void (*pSetPixel32_ROP2)(uint32 *pixel, uint32 *pen);
+
+int FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
+int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop);
+int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
+int LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 8bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "color.h"
+#include "gdi_pen.h"
+#include "gdi_bitmap.h"
+#include "gdi_region.h"
+#include "gdi_clipping.h"
+#include "gdi_drawing.h"
+
+#include "gdi_8bpp.h"
+
+int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
+{
+ /* TODO: Implement 8bpp FillRect() */
+ return 0;
+}
+
+static int BitBlt_BLACKNESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0, nWidth * hdcDest->bytesPerPixel);
+ }
+
+ return 0;
+}
+
+static int BitBlt_WHITENESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel);
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
+{
+ int y;
+ uint8 *srcp;
+ uint8 *dstp;
+
+ if ((hdcDest->selectedObject != hdcSrc->selectedObject) ||
+ gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 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);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+
+ return 0;
+ }
+
+ if (nYSrc < nYDest)
+ {
+ /* copy down (bottom to top) */
+ for (y = nHeight - 1; y >= 0; y--)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else if (nYSrc > nYDest || nXSrc > nXDest)
+ {
+ /* copy up or left (top top bottom) */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_mem(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+ else
+ {
+ /* copy straight right */
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (srcp != 0 && dstp != 0)
+ {
+ gdi_copy_memb(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCCOPY_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSTINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*dstp);
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCERASE_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = *srcp & ~(*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_NOTSRCERASE_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & ~(*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCINVERT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp ^= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCAND_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp &= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_SRCPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp |= *srcp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
+{
+ /* TODO: Implement 8bpp DSPDxax BitBlt */
+ 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;
+ uint8 *srcp;
+ uint8 *dstp;
+ uint8 *patp;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & ~(*patp);
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_DSna_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) & (*dstp);
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_MERGECOPY_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *srcp & *patp;
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_MERGEPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = ~(*srcp) | *dstp;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint8 palIndex;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ palIndex = ((hdcDest->brush->color >> 16) & 0xFF);
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp = palIndex;
+ dstp++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp;
+ patp++;
+ dstp++;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
+{
+ int x, y;
+ uint8 *dstp;
+ uint8 *patp;
+ uint8 palIndex;
+
+ if(hdcDest->brush->style == GDI_BS_SOLID)
+ {
+ palIndex = ((hdcDest->brush->color >> 16) & 0xFF);
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ *dstp ^= palIndex;
+ dstp++;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < nHeight; y++)
+ {
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *patp ^ *dstp;
+ patp++;
+ dstp++;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int BitBlt_PATPAINT_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;
+
+ for (y = 0; y < nHeight; y++)
+ {
+ srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
+ dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
+
+ if (dstp != 0)
+ {
+ for (x = 0; x < nWidth; x++)
+ {
+ patp = gdi_get_brush_pointer(hdcDest, x, y);
+
+ *dstp = *dstp | (*patp | ~(*srcp));
+ patp++;
+ srcp++;
+ dstp++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
+{
+ if (hdcSrc != NULL)
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
+ return 0;
+ }
+ else
+ {
+ if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+ }
+
+ gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCCOPY:
+ return BitBlt_SRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SPna:
+ return BitBlt_SPna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSna:
+ return BitBlt_DSna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_DSPDxax:
+ return BitBlt_DSPDxax_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;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_SRCERASE:
+ return BitBlt_SRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_NOTSRCERASE:
+ return BitBlt_NOTSRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCINVERT:
+ return BitBlt_SRCINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCAND:
+ return BitBlt_SRCAND_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_SRCPAINT:
+ return BitBlt_SRCPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGECOPY:
+ return BitBlt_MERGECOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_MERGEPAINT:
+ return BitBlt_MERGEPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
+ break;
+
+ case GDI_PATPAINT:
+ return BitBlt_PATPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
+ break;
+ }
+
+ printf("BitBlt: unknown rop: 0x%08X\n", rop);
+ return 1;
+}
+
+int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
+{
+ if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
+ return 0;
+
+ gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);
+
+ switch (rop)
+ {
+ case GDI_PATCOPY:
+ return BitBlt_PATCOPY_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_PATINVERT:
+ return BitBlt_PATINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_DSTINVERT:
+ return BitBlt_DSTINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_BLACKNESS:
+ return BitBlt_BLACKNESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+
+ case GDI_WHITENESS:
+ return BitBlt_WHITENESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
+ break;
+ }
+
+ printf("PatBlt: unknown rop: 0x%08X", rop);
+ return 1;
+}
+
+void SetPixel_BLACK_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = 0 */
+ *pixel = 0;
+}
+
+void SetPixel_NOTMERGEPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = ~(D | P) */
+ *pixel = ~(*pixel | *pen);
+}
+
+void SetPixel_MASKNOTPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = D & ~P */
+ *pixel &= ~(*pen);
+}
+
+void SetPixel_NOTCOPYPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = ~P */
+ *pixel = ~(*pen);
+}
+
+void SetPixel_MASKPENNOT_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = P & ~D */
+ *pixel = *pen & ~*pixel;
+}
+
+void SetPixel_NOT_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = ~D */
+ *pixel = ~(*pixel);
+}
+
+void SetPixel_XORPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = D ^ P */
+ *pixel = *pixel ^ *pen;
+}
+
+void SetPixel_NOTMASKPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = ~(D & P) */
+ *pixel = ~(*pixel & *pen);
+}
+
+void SetPixel_MASKPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = D & P */
+ *pixel &= *pen;
+}
+
+void SetPixel_NOTXORPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = ~(D ^ P) */
+ *pixel = ~(*pixel ^ *pen);
+}
+
+void SetPixel_NOP_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = D */
+}
+
+void SetPixel_MERGENOTPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = D | ~P */
+ *pixel |= ~(*pen);
+}
+
+void SetPixel_COPYPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = P */
+ *pixel = *pen;
+}
+
+void SetPixel_MERGEPENNOT_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = P | ~D */
+ *pixel = *pen | ~(*pixel);
+}
+
+void SetPixel_MERGEPEN_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = P | D */
+ *pixel |= *pen;
+}
+
+void SetPixel_WHITE_8bpp(uint8 *pixel, uint8 *pen)
+{
+ /* D = 1 */
+ *pixel = 0xFF;
+}
+
+pSetPixel8_ROP2 SetPixel8_ROP2_[16] =
+{
+ SetPixel_BLACK_8bpp,
+ SetPixel_NOTMERGEPEN_8bpp,
+ SetPixel_MASKNOTPEN_8bpp,
+ SetPixel_NOTCOPYPEN_8bpp,
+ SetPixel_MASKPENNOT_8bpp,
+ SetPixel_NOT_8bpp,
+ SetPixel_XORPEN_8bpp,
+ SetPixel_NOTMASKPEN_8bpp,
+ SetPixel_MASKPEN_8bpp,
+ SetPixel_NOTXORPEN_8bpp,
+ SetPixel_NOP_8bpp,
+ SetPixel_MERGENOTPEN_8bpp,
+ SetPixel_COPYPEN_8bpp,
+ SetPixel_MERGEPENNOT_8bpp,
+ SetPixel_MERGEPEN_8bpp,
+ SetPixel_WHITE_8bpp
+};
+
+int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd)
+{
+ int x, y;
+ int x1, y1;
+ int x2, y2;
+ int e, e2;
+ int dx, dy;
+ int sx, sy;
+ HGDI_BITMAP bmp;
+ int bx1, by1;
+ int bx2, by2;
+
+ int irop2;
+ uint8 pen;
+ uint8 *pixel;
+
+ x1 = hdc->pen->posX;
+ y1 = hdc->pen->posY;
+ x2 = nXEnd;
+ y2 = nYEnd;
+
+ dx = (x1 > x2) ? x1 - x2 : x2 - x1;
+ dy = (y1 > y2) ? y1 - y2 : y2 - y1;
+
+ sx = (x1 < x2) ? 1 : -1;
+ sy = (y1 < y2) ? 1 : -1;
+
+ e = dx - dy;
+
+ x = x1;
+ y = y1;
+
+ irop2 = gdi_GetROP2(hdc) - 1;
+ bmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (hdc->clip->null)
+ {
+ bx1 = (x1 < x2) ? x1 : x2;
+ by1 = (y1 < y2) ? y1 : y2;
+ bx2 = (x1 > x2) ? x1 : x2;
+ by2 = (y1 > y2) ? y1 : y2;
+ }
+ else
+ {
+ bx1 = hdc->clip->x;
+ by1 = hdc->clip->y;
+ bx2 = bx1 + hdc->clip->w - 1;
+ by2 = by1 + hdc->clip->h - 1;
+ }
+
+ pen = gdi_GetPenColor_8bpp(hdc->pen);
+
+ while (1)
+ {
+ if (!(x == x2 && y == y2))
+ {
+ if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2))
+ {
+ pixel = gdi_GetPointer_8bpp(bmp, x, y);
+ SetPixel8_ROP2_[irop2](pixel, &pen);
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ e2 = 2 * e;
+
+ if (e2 > -dy)
+ {
+ e -= dy;
+ x += sx;
+ }
+
+ if (e2 < dx)
+ {
+ e += dx;
+ y += sy;
+ }
+ }
+
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI 8bpp Internal Buffer Routines
+ *
+ * Copyright 2010-2011 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/freerdp.h>
+#include "gdi.h"
+
+typedef void (*pSetPixel8_ROP2)(uint8 *pixel, uint8 *pen);
+
+int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
+int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop);
+int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
+int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Bitmap Functions
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "color.h"
+#include "gdi_32bpp.h"
+#include "gdi_16bpp.h"
+#include "gdi_8bpp.h"
+
+#include "gdi_bitmap.h"
+
+pBitBlt BitBlt_[5] =
+{
+ NULL,
+ BitBlt_8bpp,
+ BitBlt_16bpp,
+ NULL,
+ BitBlt_32bpp
+};
+
+/**
+ * Get pixel at the given coordinates.\n
+ * @msdn{dd144909}
+ * @param hdc device context
+ * @param nXPos pixel x position
+ * @param nYPos pixel y position
+ * @return pixel color
+ */
+
+GDI_COLOR gdi_GetPixel(HGDI_DC hdc, int nXPos, int nYPos)
+{
+ HGDI_BITMAP hBmp = (HGDI_BITMAP) hdc->selectedObject;
+ GDI_COLOR* colorp = (GDI_COLOR*)&(hBmp->data[(nYPos * hBmp->width * hdc->bytesPerPixel) + nXPos * hdc->bytesPerPixel]);
+ return (GDI_COLOR) *colorp;
+}
+
+uint8 gdi_GetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return *((uint8*)&(hBmp->data[(Y * hBmp->width) + X]));
+}
+
+uint16 gdi_GetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return *((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2]));
+}
+
+uint32 gdi_GetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return *((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4]));
+}
+
+uint8* gdi_GetPointer_8bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return ((uint8*)&(hBmp->data[(Y * hBmp->width) + X]));
+}
+
+uint16* gdi_GetPointer_16bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return ((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2]));
+}
+
+uint32* gdi_GetPointer_32bpp(HGDI_BITMAP hBmp, int X, int Y)
+{
+ return ((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4]));
+}
+
+/**
+ * Set pixel at the given coordinates.\n
+ * @msdn{dd145078}
+ * @param hdc device context
+ * @param X pixel x position
+ * @param Y pixel y position
+ * @param crColor new pixel color
+ * @return
+ */
+
+GDI_COLOR gdi_SetPixel(HGDI_DC hdc, int X, int Y, GDI_COLOR crColor)
+{
+ HGDI_BITMAP hBmp = (HGDI_BITMAP) hdc->selectedObject;
+ *((GDI_COLOR*)&(hBmp->data[(Y * hBmp->width * hdc->bytesPerPixel) + X * hdc->bytesPerPixel])) = crColor;
+ return 0;
+}
+
+void gdi_SetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y, uint8 pixel)
+{
+ *((uint8*)&(hBmp->data[(Y * hBmp->width) + X])) = pixel;
+}
+
+void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, uint16 pixel)
+{
+ *((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2])) = pixel;
+}
+
+void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, uint32 pixel)
+{
+ *((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4])) = pixel;
+}
+
+/**
+ * Create a new bitmap with the given width, height, color format and pixel buffer.\n
+ * @msdn{dd183485}
+ * @param nWidth width
+ * @param nHeight height
+ * @param cBitsPerPixel bits per pixel
+ * @param data pixel buffer
+ * @return new bitmap
+ */
+
+HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, uint8* data)
+{
+ HGDI_BITMAP hBitmap = (HGDI_BITMAP) malloc(sizeof(GDI_BITMAP));
+ hBitmap->objectType = GDIOBJECT_BITMAP;
+ hBitmap->bitsPerPixel = cBitsPerPixel;
+ hBitmap->bytesPerPixel = (cBitsPerPixel + 1) / 8;
+ hBitmap->scanline = nWidth * hBitmap->bytesPerPixel;
+ hBitmap->width = nWidth;
+ hBitmap->height = nHeight;
+ hBitmap->data = data;
+ return hBitmap;
+}
+
+/**
+ * Create a new bitmap of the given width and height compatible with the current device context.\n
+ * @msdn{dd183488}
+ * @param hdc device context
+ * @param nWidth width
+ * @param nHeight height
+ * @return new bitmap
+ */
+
+HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight)
+{
+ HGDI_BITMAP hBitmap = (HGDI_BITMAP) malloc(sizeof(GDI_BITMAP));
+ hBitmap->objectType = GDIOBJECT_BITMAP;
+ hBitmap->bytesPerPixel = hdc->bytesPerPixel;
+ hBitmap->bitsPerPixel = hdc->bitsPerPixel;
+ hBitmap->width = nWidth;
+ hBitmap->height = nHeight;
+ hBitmap->data = malloc(nWidth * nHeight * hBitmap->bytesPerPixel);
+ hBitmap->scanline = nWidth * hBitmap->bytesPerPixel;
+ return hBitmap;
+}
+
+/**
+ * Perform a bit blit operation on the given pixel buffers.\n
+ * @msdn{dd183370}
+ * @param hdcDest destination device context
+ * @param nXDest destination x1
+ * @param nYDest destination y1
+ * @param nWidth width
+ * @param nHeight height
+ * @param hdcSrc source device context
+ * @param nXSrc source x1
+ * @param nYSrc source y1
+ * @param rop raster operation code
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
+{
+ pBitBlt _BitBlt = BitBlt_[IBPP(hdcDest->bitsPerPixel)];
+
+ if (_BitBlt != NULL)
+ return _BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, rop);
+ else
+ return 0;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Bitmap Functions
+ *
+ * Copyright 2010-2011 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 __GDI_BITMAP_H
+#define __GDI_BITMAP_H
+
+#include "gdi.h"
+
+GDI_COLOR gdi_GetPixel(HGDI_DC hdc, int nXPos, int nYPos);
+GDI_COLOR gdi_SetPixel(HGDI_DC hdc, int X, int Y, GDI_COLOR crColor);
+uint8 gdi_GetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y);
+uint16 gdi_GetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y);
+uint32 gdi_GetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y);
+uint8* gdi_GetPointer_8bpp(HGDI_BITMAP hBmp, int X, int Y);
+uint16* gdi_GetPointer_16bpp(HGDI_BITMAP hBmp, int X, int Y);
+uint32* gdi_GetPointer_32bpp(HGDI_BITMAP hBmp, int X, int Y);
+void gdi_SetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y, uint8 pixel);
+void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, uint16 pixel);
+void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, uint32 pixel);
+HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, uint8* data);
+HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight);
+int gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop);
+
+typedef int (*pBitBlt)(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop);
+
+#endif /* __GDI_BITMAP_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Brush Functions
+ *
+ * Copyright 2010-2011 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.
+ */
+
+/* GDI Brush Functions: http://msdn.microsoft.com/en-us/library/dd183395/ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_32bpp.h"
+#include "gdi_16bpp.h"
+#include "gdi_8bpp.h"
+
+#include "gdi_brush.h"
+
+pPatBlt PatBlt_[5] =
+{
+ NULL,
+ PatBlt_8bpp,
+ PatBlt_16bpp,
+ NULL,
+ PatBlt_32bpp
+};
+
+/**
+ * Create a new solid brush.\n
+ * @msdn{dd183518}
+ * @param crColor brush color
+ * @return new brush
+ */
+
+HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor)
+{
+ HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
+ hBrush->objectType = GDIOBJECT_BRUSH;
+ hBrush->style = GDI_BS_SOLID;
+ hBrush->color = crColor;
+ return hBrush;
+}
+
+/**
+ * Create a new pattern brush.\n
+ * @msdn{dd183508}
+ * @param hbmp pattern bitmap
+ * @return new brush
+ */
+
+HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
+{
+ HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
+ hBrush->objectType = GDIOBJECT_BRUSH;
+ hBrush->style = GDI_BS_PATTERN;
+ hBrush->pattern = hbmp;
+ return hBrush;
+}
+
+/**
+ * Perform a pattern blit operation on the given pixel buffer.\n
+ * @msdn{dd162778}
+ * @param hdc device context
+ * @param nXLeft x1
+ * @param nYLeft y1
+ * @param nWidth width
+ * @param nHeight height
+ * @param rop raster operation code
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
+{
+ pPatBlt _PatBlt = PatBlt_[IBPP(hdc->bitsPerPixel)];
+
+ if (_PatBlt != NULL)
+ return _PatBlt(hdc, nXLeft, nYLeft, nWidth, nHeight, rop);
+ else
+ return 0;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Brush Functions
+ *
+ * Copyright 2010-2011 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 __GDI_BRUSH_H
+#define __GDI_BRUSH_H
+
+#include "gdi.h"
+
+HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
+HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
+int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
+
+typedef int (*pPatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
+
+#endif /* __GDI_BRUSH_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Clipping Functions
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "gdi_region.h"
+
+#include "gdi_clipping.h"
+
+int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight)
+{
+ return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight);
+}
+
+/**
+ * Get the current clipping region.\n
+ * @msdn{dd144866}
+ * @param hdc device context
+ * @return clipping region
+ */
+
+HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc)
+{
+ return hdc->clip;
+}
+
+/**
+ * Set the current clipping region to null.
+ * @param hdc device context
+ * @return
+ */
+
+int gdi_SetNullClipRgn(HGDI_DC hdc)
+{
+ gdi_SetClipRgn(hdc, 0, 0, 0, 0);
+ hdc->clip->null = 1;
+ return 0;
+}
+
+/**
+ * Clip coordinates according to clipping region
+ * @param hdc device context
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ * @param srcx source x1
+ * @param srcy source y1
+ * @return 1 if there is something to draw, 0 otherwise
+ */
+
+int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy)
+{
+ GDI_RECT bmp;
+ GDI_RECT clip;
+ GDI_RECT coords;
+ HGDI_BITMAP hBmp;
+
+ int dx = 0;
+ int dy = 0;
+ int draw = 1;
+
+ if (hdc == NULL)
+ return 0;
+
+ hBmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (hBmp != NULL)
+ {
+ if (hdc->clip->null)
+ {
+ gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &clip);
+ }
+ else
+ {
+ gdi_RgnToRect(hdc->clip, &clip);
+ gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &bmp);
+
+ if (clip.left < bmp.left)
+ clip.left = bmp.left;
+
+ if (clip.right > bmp.right)
+ clip.right = bmp.right;
+
+ if (clip.top < bmp.top)
+ clip.top = bmp.top;
+
+ if (clip.bottom > bmp.bottom)
+ clip.bottom = bmp.bottom;
+ }
+ }
+ else
+ {
+ gdi_RgnToRect(hdc->clip, &clip);
+ }
+
+ gdi_CRgnToRect(*x, *y, *w, *h, &coords);
+
+ if (coords.right >= clip.left && coords.left <= clip.right &&
+ coords.bottom >= clip.top && coords.top <= clip.bottom)
+ {
+ /* coordinates overlap with clipping region */
+
+ if (coords.left < clip.left)
+ {
+ dx = (clip.left - coords.left) + 1;
+ coords.left = clip.left;
+ }
+
+ if (coords.right > clip.right)
+ coords.right = clip.right;
+
+ if (coords.top < clip.top)
+ {
+ dy = (clip.top - coords.top) + 1;
+ coords.top = clip.top;
+ }
+
+ if (coords.bottom > clip.bottom)
+ coords.bottom = clip.bottom;
+ }
+ else
+ {
+ /* coordinates do not overlap with clipping region */
+
+ coords.left = 0;
+ coords.right = 0;
+ coords.top = 0;
+ coords.bottom = 0;
+ draw = 0;
+ }
+
+ if (srcx != NULL)
+ {
+ if (dx > 0)
+ {
+ *srcx += dx - 1;
+ }
+ }
+
+ if (srcy != NULL)
+ {
+ if (dy > 0)
+ {
+ *srcy += dy - 1;
+ }
+ }
+
+ gdi_RectToCRgn(&coords, x, y, w, h);
+
+ return draw;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Clipping Functions
+ *
+ * Copyright 2010-2011 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 __GDI_CLIPPING_H
+#define __GDI_CLIPPING_H
+
+#include "gdi.h"
+
+int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight);
+HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc);
+int gdi_SetNullClipRgn(HGDI_DC hdc);
+int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy);
+
+#endif /* __GDI_CLIPPING_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Device Context Functions
+ *
+ * Copyright 2010-2011 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.
+ */
+
+/* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "gdi_region.h"
+
+#include "gdi_dc.h"
+
+/**
+ * Get the current device context (a new one is created each time).\n
+ * @msdn{dd144871}
+ * @return current device context
+ */
+
+HGDI_DC gdi_GetDC()
+{
+ HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC));
+ hDC->bytesPerPixel = 4;
+ hDC->bitsPerPixel = 32;
+ hDC->drawMode = GDI_R2_BLACK;
+ hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0);
+ hDC->clip->null = 1;
+ hDC->hwnd = NULL;
+ return hDC;
+}
+
+/**
+ * Create a new device context compatible with the given device context.\n
+ * @msdn{dd183489}
+ * @param hdc device context
+ * @return new compatible device context
+ */
+
+HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc)
+{
+ HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC));
+ hDC->bytesPerPixel = hdc->bytesPerPixel;
+ hDC->bitsPerPixel = hdc->bitsPerPixel;
+ hDC->drawMode = hdc->drawMode;
+ hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0);
+ hDC->clip->null = 1;
+ hDC->hwnd = NULL;
+ hDC->alpha = hdc->alpha;
+ hDC->invert = hdc->invert;
+ hDC->rgb555 = hdc->rgb555;
+ return hDC;
+}
+
+/**
+ * Select a GDI object in the current device context.\n
+ * @msdn{dd162957}
+ * @param hdc device context
+ * @param hgdiobject new selected GDI object
+ * @return previous selected GDI object
+ */
+
+HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject)
+{
+ HGDIOBJECT previousSelectedObject = hdc->selectedObject;
+
+ if (hgdiobject == NULL)
+ return NULL;
+
+ if (hgdiobject->objectType == GDIOBJECT_BITMAP)
+ {
+ hdc->selectedObject = hgdiobject;
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_PEN)
+ {
+ previousSelectedObject = (HGDIOBJECT) hdc->pen;
+ hdc->pen = (HGDI_PEN) hgdiobject;
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
+ {
+ previousSelectedObject = (HGDIOBJECT) hdc->brush;
+ hdc->brush = (HGDI_BRUSH) hgdiobject;
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_REGION)
+ {
+ hdc->selectedObject = hgdiobject;
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_RECT)
+ {
+ hdc->selectedObject = hgdiobject;
+ }
+ else
+ {
+ /* Unknown GDI Object Type */
+ return 0;
+ }
+
+ return previousSelectedObject;
+}
+
+/**
+ * Delete a GDI object.\n
+ * @msdn{dd183539}
+ * @param hgdiobject GDI object
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_DeleteObject(HGDIOBJECT hgdiobject)
+{
+ if (hgdiobject == NULL)
+ return 0;
+
+ if (hgdiobject->objectType == GDIOBJECT_BITMAP)
+ {
+ HGDI_BITMAP hBitmap = (HGDI_BITMAP) hgdiobject;
+
+ if (hBitmap->data != NULL)
+ free(hBitmap->data);
+
+ free(hBitmap);
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_PEN)
+ {
+ HGDI_PEN hPen = (HGDI_PEN) hgdiobject;
+ free(hPen);
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
+ {
+ HGDI_BRUSH hBrush = (HGDI_BRUSH) hgdiobject;
+
+ if(hBrush->style == GDI_BS_PATTERN)
+ gdi_DeleteObject((HGDIOBJECT) hBrush->pattern);
+
+ free(hBrush);
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_REGION)
+ {
+ free(hgdiobject);
+ }
+ else if (hgdiobject->objectType == GDIOBJECT_RECT)
+ {
+ free(hgdiobject);
+ }
+ else
+ {
+ /* Unknown GDI Object Type */
+ free(hgdiobject);
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Delete device context.\n
+ * @msdn{dd183533}
+ * @param hdc device context
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_DeleteDC(HGDI_DC hdc)
+{
+ if (hdc->hwnd)
+ {
+ free(hdc->hwnd->invalid);
+ free(hdc->hwnd);
+ }
+
+ free(hdc->clip);
+ free(hdc);
+
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Device Context Functions
+ *
+ * Copyright 2010-2011 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 __GDI_DC_H
+#define __GDI_DC_H
+
+#include "gdi.h"
+
+HGDI_DC gdi_GetDC();
+HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc);
+HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject);
+int gdi_DeleteObject(HGDIOBJECT hgdiobject);
+int gdi_DeleteDC(HGDI_DC hdc);
+
+#endif /* __GDI_DC_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Drawing Functions
+ *
+ * Copyright 2010-2011 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.
+ */
+
+/* GDI Drawing Functions: http://msdn.microsoft.com/en-us/library/dd162760/ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_dc.h"
+
+/**
+ * Set current foreground draw mode.\n
+ * @msdn{dd144922}
+ * @param hdc device context
+ * @return draw mode
+ */
+
+int gdi_GetROP2(HGDI_DC hdc)
+{
+ return hdc->drawMode;
+}
+
+/**
+ * Set current foreground draw mode.\n
+ * @msdn{dd145088}
+ * @param hdc device context
+ * @param fnDrawMode draw mode
+ * @return previous draw mode
+ */
+
+int gdi_SetROP2(HGDI_DC hdc, int fnDrawMode)
+{
+ int prevDrawMode = hdc->drawMode;
+
+ if (fnDrawMode > 0 && fnDrawMode <= 16)
+ hdc->drawMode = fnDrawMode;
+
+ return prevDrawMode;
+}
+
+/**
+ * Get the current background color.\n
+ * @msdn{dd144852}
+ * @param hdc device context
+ * @return background color
+ */
+
+GDI_COLOR gdi_GetBkColor(HGDI_DC hdc)
+{
+ return hdc->bkColor;
+}
+
+/**
+ * Set the current background color.\n
+ * @msdn{dd162964}
+ * @param hdc device color
+ * @param crColor new background color
+ * @return previous background color
+ */
+
+GDI_COLOR gdi_SetBkColor(HGDI_DC hdc, GDI_COLOR crColor)
+{
+ GDI_COLOR previousBkColor = hdc->bkColor;
+ hdc->bkColor = crColor;
+ return previousBkColor;
+}
+
+/**
+ * Get the current background mode.\n
+ * @msdn{dd144853}
+ * @param hdc device context
+ * @return background mode
+ */
+
+int gdi_GetBkMode(HGDI_DC hdc)
+{
+ return hdc->bkMode;
+}
+
+/**
+ * Set the current background mode.\n
+ * @msdn{dd162965}
+ * @param hdc device context
+ * @param iBkMode background mode
+ * @return
+ */
+
+int gdi_SetBkMode(HGDI_DC hdc, int iBkMode)
+{
+ if (iBkMode == GDI_OPAQUE || iBkMode == GDI_TRANSPARENT)
+ hdc->bkMode = iBkMode;
+ else
+ hdc->bkMode = GDI_OPAQUE;
+
+ return 0;
+}
+
+/**
+ * Set the current text color.\n
+ * @msdn{dd145093}
+ * @param hdc device context
+ * @param crColor new text color
+ * @return previous text color
+ */
+
+GDI_COLOR gdi_SetTextColor(HGDI_DC hdc, GDI_COLOR crColor)
+{
+ GDI_COLOR previousTextColor = hdc->textColor;
+ hdc->textColor = crColor;
+ return previousTextColor;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Drawing Functions
+ *
+ * Copyright 2010-2011 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 __GDI_DRAWING_H
+#define __GDI_DRAWING_H
+
+#include "gdi.h"
+
+int gdi_GetROP2(HGDI_DC hdc);
+int gdi_SetROP2(HGDI_DC hdc, int fnDrawMode);
+GDI_COLOR gdi_GetBkColor(HGDI_DC hdc);
+GDI_COLOR gdi_SetBkColor(HGDI_DC hdc, GDI_COLOR crColor);
+int gdi_GetBkMode(HGDI_DC hdc);
+int gdi_SetBkMode(HGDI_DC hdc, int iBkMode);
+GDI_COLOR gdi_SetTextColor(HGDI_DC hdc, GDI_COLOR crColor);
+
+#endif /* __GDI_DRAWING_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Line Functions
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_32bpp.h"
+#include "gdi_16bpp.h"
+#include "gdi_8bpp.h"
+
+#include "gdi_line.h"
+
+pLineTo LineTo_[5] =
+{
+ NULL,
+ LineTo_8bpp,
+ LineTo_16bpp,
+ NULL,
+ LineTo_32bpp
+};
+
+/**
+ * Draw a line from the current position to the given position.\n
+ * @msdn{dd145029}
+ * @param hdc device context
+ * @param nXEnd ending x position
+ * @param nYEnd ending y position
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd)
+{
+ pLineTo _LineTo = LineTo_[IBPP(hdc->bitsPerPixel)];
+
+ if (_LineTo != NULL)
+ return _LineTo(hdc, nXEnd, nYEnd);
+ else
+ return 0;
+}
+
+/**
+ * Draw one or more straight lines
+ * @param hdc device context
+ * @param lppt array of points
+ * @param cCount number of points
+ * @return
+ */
+int gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, int cCount)
+{
+ int i;
+ for (i = 0; i < cCount; i++)
+ {
+ gdi_LineTo(hdc, lppt[i].x, lppt[i].y);
+ gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL);
+ }
+
+ return 1;
+}
+
+/**
+ * Draw one or more straight lines
+ * @param hdc device context
+ * @param lppt array of points
+ * @param cPoints number of points
+ * @return
+ */
+int gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints)
+{
+ if (cPoints > 0)
+ {
+ int i;
+ GDI_POINT pt;
+
+ gdi_MoveToEx(hdc, lppt[0].x, lppt[0].y, &pt);
+
+ for (i = 0; i < cPoints; i++)
+ {
+ gdi_LineTo(hdc, lppt[i].x, lppt[i].y);
+ gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL);
+ }
+
+ gdi_MoveToEx(hdc, pt.x, pt.y, NULL);
+ }
+
+ return 1;
+}
+
+/**
+ * Draw multiple series of connected line segments
+ * @param hdc device context
+ * @param lppt array of points
+ * @param lpdwPolyPoints array of numbers of points per series
+ * @param cCount count of entries in lpdwPolyPoints
+ * @return
+ */
+int gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, int cCount)
+{
+ int cPoints;
+ int i, j = 0;
+
+ for (i = 0; i < cCount; i++)
+ {
+ cPoints = lpdwPolyPoints[i];
+ gdi_Polyline(hdc, &lppt[j], cPoints);
+ j += cPoints;
+ }
+
+ return 1;
+}
+
+/**
+ * Move pen from the current device context to a new position.
+ * @param hdc device context
+ * @param X x position
+ * @param Y y position
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint)
+{
+ if (lpPoint != NULL)
+ {
+ lpPoint->x = hdc->pen->posX;
+ lpPoint->y = hdc->pen->posY;
+ }
+
+ hdc->pen->posX = X;
+ hdc->pen->posY = Y;
+
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Line Functions
+ *
+ * Copyright 2010-2011 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 __GDI_LINE_H
+#define __GDI_LINE_H
+
+#include "gdi.h"
+
+int gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd);
+int gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, int cCount);
+int gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints);
+int gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, int cCount);
+int gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint);
+
+typedef int (*pLineTo)(HGDI_DC hdc, int nXEnd, int nYEnd);
+
+#endif /* __GDI_LINE_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Palette Functions
+ *
+ * Copyright 2010-2011 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.
+ */
+
+/* GDI Palette Functions: http://msdn.microsoft.com/en-us/library/dd183454/ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_palette.h"
+
+static HGDI_PALETTE hSystemPalette = NULL;
+
+static const GDI_PALETTEENTRY default_system_palette[20] =
+{
+ /* First 10 entries */
+ { 0x00, 0x00, 0x00 },
+ { 0x80, 0x00, 0x00 },
+ { 0x00, 0x80, 0x00 },
+ { 0x80, 0x80, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x80, 0x00, 0x80 },
+ { 0x00, 0x80, 0x80 },
+ { 0xC0, 0xC0, 0xC0 },
+ { 0xC0, 0xDC, 0xC0 },
+ { 0xA6, 0xCA, 0xF0 },
+
+ /* Last 10 entries */
+ { 0xFF, 0xFB, 0xF0 },
+ { 0xA0, 0xA0, 0xA4 },
+ { 0x80, 0x80, 0x80 },
+ { 0xFF, 0x00, 0x00 },
+ { 0x00, 0xFF, 0x00 },
+ { 0xFF, 0xFF, 0x00 },
+ { 0x00, 0x00, 0xFF },
+ { 0xFF, 0x00, 0xFF },
+ { 0x00, 0xFF, 0xFF },
+ { 0xFF, 0xFF, 0xFF }
+};
+
+/**
+ * Create a new palette.\n
+ * @msdn{dd183507}
+ * @param original palette
+ * @return new palette
+ */
+
+HGDI_PALETTE gdi_CreatePalette(HGDI_PALETTE palette)
+{
+ HGDI_PALETTE hPalette = (HGDI_PALETTE) malloc(sizeof(GDI_PALETTE));
+ hPalette->count = palette->count;
+ hPalette->entries = (GDI_PALETTEENTRY*) malloc(sizeof(GDI_PALETTEENTRY) * hPalette->count);
+ memcpy(hPalette->entries, palette->entries, sizeof(GDI_PALETTEENTRY) * hPalette->count);
+ return hPalette;
+}
+
+/**
+ * Create system palette\n
+ * @return system palette
+ */
+
+HGDI_PALETTE CreateSystemPalette()
+{
+ HGDI_PALETTE palette = (HGDI_PALETTE) malloc(sizeof(GDI_PALETTE));
+
+ palette->count = 256;
+ palette->entries = (GDI_PALETTEENTRY*) malloc(sizeof(GDI_PALETTEENTRY) * 256);
+ memset(palette->entries, 0, sizeof(GDI_PALETTEENTRY) * 256);
+
+ memcpy(&palette->entries[0], &default_system_palette[0], 10 * sizeof(GDI_PALETTEENTRY));
+ memcpy(&palette->entries[256 - 10], &default_system_palette[10], 10 * sizeof(GDI_PALETTEENTRY));
+
+ return palette;
+}
+
+/**
+ * Get system palette\n
+ * @return system palette
+ */
+
+HGDI_PALETTE gdi_GetSystemPalette()
+{
+ if (hSystemPalette == NULL)
+ hSystemPalette = CreateSystemPalette();
+
+ return hSystemPalette;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Palette Functions
+ *
+ * Copyright 2010-2011 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 __GDI_PALETTE_H
+#define __GDI_PALETTE_H
+
+#include "gdi.h"
+
+HGDI_PALETTE gdi_CreatePalette(HGDI_PALETTE palette);
+HGDI_PALETTE gdi_GetSystemPalette();
+
+#endif /* __GDI_PALETTE_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Pen Functions
+ *
+ * Copyright 2010-2011 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.
+ */
+
+/* GDI Pen Functions: http://msdn.microsoft.com/en-us/library/dd162790 */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_pen.h"
+
+/**
+ * Create a new pen.\n
+ * @msdn{dd183509}
+ * @param fnPenStyle pen style
+ * @param nWidth pen width
+ * @param crColor pen color
+ * @return new pen
+ */
+
+HGDI_PEN gdi_CreatePen(int fnPenStyle, int nWidth, int crColor)
+{
+ HGDI_PEN hPen = (HGDI_PEN) malloc(sizeof(GDI_PEN));
+ hPen->objectType = GDIOBJECT_PEN;
+ hPen->style = fnPenStyle;
+ hPen->color = crColor;
+ hPen->width = nWidth;
+ return hPen;
+}
+
+uint8 gdi_GetPenColor_8bpp(HGDI_PEN pen)
+{
+ /* TODO: implement conversion using palette */
+ return 0xFF;
+}
+
+uint16 gdi_GetPenColor_16bpp(HGDI_PEN pen)
+{
+ uint16 p;
+ int r, g, b;
+ GetRGB32(r, g, b, pen->color);
+ RGB_888_565(r, g, b);
+ p = RGB16(r, g, b);
+ return p;
+}
+
+uint32 gdi_GetPenColor_32bpp(HGDI_PEN pen)
+{
+ return pen->color;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Pen Functions
+ *
+ * Copyright 2010-2011 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 __GDI_PEN_H
+#define __GDI_PEN_H
+
+#include "gdi.h"
+
+HGDI_PEN gdi_CreatePen(int fnPenStyle, int nWidth, int crColor);
+uint8 gdi_GetPenColor_8bpp(HGDI_PEN pen);
+uint16 gdi_GetPenColor_16bpp(HGDI_PEN pen);
+uint32 gdi_GetPenColor_32bpp(HGDI_PEN pen);
+
+#endif /* __GDI_PEN_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Region Functions
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include "gdi.h"
+
+#include "gdi_region.h"
+
+/**
+ * Create a region from rectangular coordinates.\n
+ * @msdn{dd183514}
+ * @param nLeftRect x1
+ * @param nTopRect y1
+ * @param nRightRect x2
+ * @param nBottomRect y2
+ * @return new region
+ */
+
+HGDI_RGN gdi_CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
+{
+ HGDI_RGN hRgn = (HGDI_RGN) malloc(sizeof(GDI_RGN));
+ hRgn->objectType = GDIOBJECT_REGION;
+ hRgn->x = nLeftRect;
+ hRgn->y = nTopRect;
+ hRgn->w = nRightRect - nLeftRect + 1;
+ hRgn->h = nBottomRect - nTopRect + 1;
+ hRgn->null = 0;
+ return hRgn;
+}
+
+/**
+ * Create a new rectangle.
+ * @param xLeft x1
+ * @param yTop y1
+ * @param xRight x2
+ * @param yBottom y2
+ * @return new rectangle
+ */
+
+HGDI_RECT gdi_CreateRect(int xLeft, int yTop, int xRight, int yBottom)
+{
+ HGDI_RECT hRect = (HGDI_RECT) malloc(sizeof(GDI_RECT));
+ hRect->objectType = GDIOBJECT_RECT;
+ hRect->left = xLeft;
+ hRect->top = yTop;
+ hRect->right = xRight;
+ hRect->bottom = yBottom;
+ return hRect;
+}
+
+/**
+ * Convert a rectangle to a region.
+ * @param rect source rectangle
+ * @param rgn destination region
+ */
+
+void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn)
+{
+ rgn->x = rect->left;
+ rgn->y = rect->top;
+ rgn->w = rect->right - rect->left + 1;
+ rgn->h = rect->bottom - rect->top + 1;
+}
+
+/**
+ * Convert rectangular coordinates to a region.
+ * @param left x1
+ * @param top y1
+ * @param right x2
+ * @param bottom y2
+ * @param rgn destination region
+ */
+
+void gdi_CRectToRgn(int left, int top, int right, int bottom, HGDI_RGN rgn)
+{
+ rgn->x = left;
+ rgn->y = top;
+ rgn->w = right - left + 1;
+ rgn->h = bottom - top + 1;
+}
+
+/**
+ * Convert a rectangle to region coordinates.
+ * @param rect source rectangle
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ */
+
+void gdi_RectToCRgn(HGDI_RECT rect, int *x, int *y, int *w, int *h)
+{
+ *x = rect->left;
+ *y = rect->top;
+ *w = rect->right - rect->left + 1;
+ *h = rect->bottom - rect->top + 1;
+}
+
+/**
+ * Convert rectangular coordinates to region coordinates.
+ * @param left x1
+ * @param top y1
+ * @param right x2
+ * @param bottom y2
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ */
+
+void gdi_CRectToCRgn(int left, int top, int right, int bottom, int *x, int *y, int *w, int *h)
+{
+ *x = left;
+ *y = top;
+ *w = right - left + 1;
+ *h = bottom - top + 1;
+}
+
+/**
+ * Convert a region to a rectangle.
+ * @param rgn source region
+ * @param rect destination rectangle
+ */
+
+void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect)
+{
+ rect->left = rgn->x;
+ rect->top = rgn->y;
+ rect->right = rgn->x + rgn->w - 1;
+ rect->bottom = rgn->y + rgn->h - 1;
+}
+
+/**
+ * Convert region coordinates to a rectangle.
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ * @param rect destination rectangle
+ */
+
+void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect)
+{
+ rect->left = x;
+ rect->top = y;
+ rect->right = x + w - 1;
+ rect->bottom = y + h - 1;
+}
+
+/**
+ * Convert a region to rectangular coordinates.
+ * @param rgn source region
+ * @param left x1
+ * @param top y1
+ * @param right x2
+ * @param bottom y2
+ */
+
+void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom)
+{
+ *left = rgn->x;
+ *top = rgn->y;
+ *right = rgn->x + rgn->w - 1;
+ *bottom = rgn->y + rgn->h - 1;
+}
+
+/**
+ * Convert region coordinates to rectangular coordinates.
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ * @param left x1
+ * @param top y1
+ * @param right x2
+ * @param bottom y2
+ */
+
+void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom)
+{
+ *left = x;
+ *top = y;
+ *right = x + w - 1;
+ *bottom = y + h - 1;
+}
+
+/**
+ * Check if copying would involve overlapping regions
+ * @param x x1
+ * @param y y1
+ * @param width width
+ * @param height height
+ * @param srcx source x1
+ * @param srcy source y1
+ * @return 1 if there is an overlap, 0 otherwise
+ */
+
+int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy)
+{
+ GDI_RECT dst;
+ GDI_RECT src;
+
+ gdi_CRgnToRect(x, y, width, height, &dst);
+ gdi_CRgnToRect(srcx, srcy, width, height, &src);
+
+ return (dst.right > src.left && dst.left < src.right &&
+ dst.bottom > src.top && dst.top < src.bottom) ? 1 : 0;
+}
+
+/**
+ * Set the coordinates of a given rectangle.\n
+ * @msdn{dd145085}
+ * @param rc rectangle
+ * @param xLeft x1
+ * @param yTop y1
+ * @param xRight x2
+ * @param yBottom y2
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom)
+{
+ rc->left = xLeft;
+ rc->top = yTop;
+ rc->right = xRight;
+ rc->bottom = yBottom;
+ return 1;
+}
+
+/**
+ * Set the coordinates of a given region.
+ * @param hRgn region
+ * @param nXLeft x1
+ * @param nYLeft y1
+ * @param nWidth width
+ * @param nHeight height
+ * @return
+ */
+
+int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight)
+{
+ hRgn->x = nXLeft;
+ hRgn->y = nYLeft;
+ hRgn->w = nWidth;
+ hRgn->h = nHeight;
+ hRgn->null = 0;
+ return 0;
+}
+
+/**
+ * Convert rectangular coordinates to a region
+ * @param hRgn destination region
+ * @param nLeftRect x1
+ * @param nTopRect y1
+ * @param nRightRect x2
+ * @param nBottomRect y2
+ * @return
+ */
+
+int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
+{
+ gdi_CRectToRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, hRgn);
+ hRgn->null = 0;
+ return 0;
+}
+
+/**
+ * Set the current clipping region coordinates.
+ * @param hdc device context
+ * @param nXLeft x1
+ * @param nYLeft y1
+ * @param nWidth width
+ * @param nHeight height
+ * @return
+ */
+
+/**
+ * Compare two regions for equality.\n
+ * @msdn{dd162700}
+ * @param hSrcRgn1 first region
+ * @param hSrcRgn2 second region
+ * @return 1 if both regions are equal, 0 otherwise
+ */
+
+int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2)
+{
+ if ((hSrcRgn1->x == hSrcRgn2->x) &&
+ (hSrcRgn1->y == hSrcRgn2->y) &&
+ (hSrcRgn1->w == hSrcRgn2->w) &&
+ (hSrcRgn1->h == hSrcRgn2->h))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Copy coordinates from a rectangle to another rectangle
+ * @param dst destination rectangle
+ * @param src source rectangle
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src)
+{
+ dst->left = src->left;
+ dst->top = src->top;
+ dst->right = src->right;
+ dst->bottom = src->bottom;
+ return 1;
+}
+
+/**
+ * Check if a point is inside a rectangle.\n
+ * @msdn{dd162882}
+ * @param rc rectangle
+ * @param x point x position
+ * @param y point y position
+ * @return 1 if the point is inside, 0 otherwise
+ */
+
+int gdi_PtInRect(HGDI_RECT rc, int x, int y)
+{
+ /*
+ * points on the left and top sides are considered in,
+ * while points on the right and bottom sides are considered out
+ */
+
+ if (x >= rc->left && x <= rc->right)
+ {
+ if (y >= rc->top && y <= rc->bottom)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Invalidate a given region, such that it is redrawn on the next region update.\n
+ * @msdn{dd145003}
+ * @param hdc device context
+ * @param x x1
+ * @param y y1
+ * @param w width
+ * @param h height
+ * @return
+ */
+
+int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h)
+{
+ GDI_RECT inv;
+ GDI_RECT rgn;
+ HGDI_RGN invalid;
+ HGDI_BITMAP bmp;
+
+ if (hdc->hwnd == NULL)
+ return 0;
+
+ if (hdc->hwnd->invalid == NULL)
+ return 0;
+
+ invalid = hdc->hwnd->invalid;
+ bmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (invalid->null)
+ {
+ invalid->x = x;
+ invalid->y = y;
+ invalid->w = w;
+ invalid->h = h;
+ invalid->null = 0;
+ return 0;
+ }
+
+ gdi_CRgnToRect(x, y, w, h, &rgn);
+ gdi_RgnToRect(invalid, &inv);
+
+ if (rgn.left < 0)
+ rgn.left = 0;
+
+ if (rgn.top < 0)
+ rgn.top = 0;
+
+ if (rgn.left < inv.left)
+ inv.left = rgn.left;
+
+ if (rgn.top < inv.top)
+ inv.top = rgn.top;
+
+ if (rgn.right > inv.right)
+ inv.right = rgn.right;
+
+ if (rgn.bottom > inv.bottom)
+ inv.bottom = rgn.bottom;
+
+ gdi_RectToRgn(&inv, invalid);
+
+ return 0;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Region Functions
+ *
+ * Copyright 2010-2011 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 __GDI_REGION_H
+#define __GDI_REGION_H
+
+#include "gdi.h"
+
+HGDI_RGN gdi_CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
+HGDI_RECT gdi_CreateRect(int xLeft, int yTop, int xRight, int yBottom);
+void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn);
+void gdi_CRectToRgn(int left, int top, int right, int bottom, HGDI_RGN rgn);
+void gdi_RectToCRgn(HGDI_RECT rect, int *x, int *y, int *w, int *h);
+void gdi_CRectToCRgn(int left, int top, int right, int bottom, int *x, int *y, int *w, int *h);
+void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect);
+void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect);
+void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom);
+void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom);
+int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy);
+int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom);
+int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight);
+int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
+int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2);
+int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src);
+int gdi_PtInRect(HGDI_RECT rc, int x, int y);
+int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h);
+
+#endif /* __GDI_REGION_H */
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Shape Functions
+ *
+ * Copyright 2010-2011 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <freerdp/freerdp.h>
+
+#include "gdi.h"
+#include "gdi_8bpp.h"
+#include "gdi_16bpp.h"
+#include "gdi_32bpp.h"
+#include "gdi_bitmap.h"
+
+#include "gdi_shape.h"
+
+pFillRect FillRect_[5] =
+{
+ NULL,
+ FillRect_8bpp,
+ FillRect_16bpp,
+ NULL,
+ FillRect_32bpp
+};
+
+static void Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2)
+{
+ int i;
+ long e, e2;
+ long dx, dy;
+ int a, b, c;
+ int bx1, by1;
+ int bx2, by2;
+
+ HGDI_BITMAP bmp;
+ uint8 pixel8;
+ uint16 pixel16;
+ uint32 pixel32;
+ int bpp = hdc->bitsPerPixel;
+
+ a = (x1 < x2) ? x2 - x1 : x1 - x2;
+ b = (y1 < y2) ? y2 - y1 : y1 - y2;
+ c = b & 1;
+
+ dx = 4 * (1 - a) * b * b;
+ dy = 4 * (c + 1) * a * a;
+ e = dx + dy + c * a * a;
+
+ if (x1 > x2)
+ {
+ x1 = x2;
+ x2 += a;
+ }
+
+ if (y1 > y2)
+ y1 = y2;
+
+ y1 += (b + 1) / 2;
+ y2 = y1 - c;
+
+ a *= 8 * a;
+ c = 8 * b * b;
+
+ pixel8 = 0;
+ pixel16 = 0;
+ pixel32 = 0;
+ bmp = (HGDI_BITMAP) hdc->selectedObject;
+
+ if (hdc->clip->null)
+ {
+ bx1 = (x1 < x2) ? x1 : x2;
+ by1 = (y1 < y2) ? y1 : y2;
+ bx2 = (x1 > x2) ? x1 : x2;
+ by2 = (y1 > y2) ? y1 : y2;
+ }
+ else
+ {
+ bx1 = hdc->clip->x;
+ by1 = hdc->clip->y;
+ bx2 = bx1 + hdc->clip->w - 1;
+ by2 = by1 + hdc->clip->h - 1;
+ }
+
+ do
+ {
+ if (bpp == 32)
+ {
+ gdi_SetPixel_32bpp(bmp, x2, y1, pixel32);
+ gdi_SetPixel_32bpp(bmp, x1, y1, pixel32);
+ gdi_SetPixel_32bpp(bmp, x1, y2, pixel32);
+ gdi_SetPixel_32bpp(bmp, x2, y2, pixel32);
+ }
+ else if (bpp == 16)
+ {
+ gdi_SetPixel_16bpp(bmp, x2, y1, pixel16);
+ gdi_SetPixel_16bpp(bmp, x1, y1, pixel16);
+ gdi_SetPixel_16bpp(bmp, x1, y2, pixel16);
+ gdi_SetPixel_16bpp(bmp, x2, y2, pixel16);
+ }
+ else if (bpp == 8)
+ {
+ for (i = x1; i < x2; i++)
+ {
+ gdi_SetPixel_8bpp(bmp, i, y1, pixel8);
+ gdi_SetPixel_8bpp(bmp, i, y2, pixel8);
+ }
+
+ for (i = y1; i < y2; i++)
+ {
+ gdi_SetPixel_8bpp(bmp, x1, i, pixel8);
+ gdi_SetPixel_8bpp(bmp, x2, i, pixel8);
+ }
+ }
+
+ e2 = 2 * e;
+
+ if (e2 >= dx)
+ {
+ x1++;
+ x2--;
+ e += dx += c;
+ }
+
+ if (e2 <= dy)
+ {
+ y1++;
+ y2--;
+ e += dy += a;
+ }
+ }
+ while (x1 <= x2);
+
+ while (y1 - y2 < b)
+ {
+ if (bpp == 32)
+ {
+ gdi_SetPixel_32bpp(bmp, x1 - 1, ++y1, pixel32);
+ gdi_SetPixel_32bpp(bmp, x1 - 1, --y2, pixel32);
+ }
+ else if (bpp == 16)
+ {
+ gdi_SetPixel_16bpp(bmp, x1 - 1, ++y1, pixel16);
+ gdi_SetPixel_16bpp(bmp, x1 - 1, --y2, pixel16);
+ }
+ else if (bpp == 8)
+ {
+ gdi_SetPixel_8bpp(bmp, x1 - 1, ++y1, pixel8);
+ gdi_SetPixel_8bpp(bmp, x1 - 1, --y2, pixel8);
+ }
+ }
+}
+
+/**
+ * Draw an ellipse
+ * @param hdc device context
+ * @param nLeftRect x1
+ * @param nTopRect y1
+ * @param nRightRect x2
+ * @param nBottomRect y2
+ * @return
+ */
+int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
+{
+ Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
+ return 1;
+}
+
+/**
+ * Fill a rectangle with the given brush.\n
+ * @msdn{dd162719}
+ * @param hdc device context
+ * @param rect rectangle
+ * @param hbr brush
+ * @return 1 if successful, 0 otherwise
+ */
+
+int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
+{
+ pFillRect _FillRect = FillRect_[IBPP(hdc->bitsPerPixel)];
+
+ if (_FillRect != NULL)
+ return _FillRect(hdc, rect, hbr);
+ else
+ return 0;
+}
+
+/**
+ *
+ * @param hdc device context
+ * @param lpPoints array of points
+ * @param nCount number of points
+ * @return
+ */
+int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount)
+{
+ return 1;
+}
+
+/**
+ * Draw a series of closed polygons
+ * @param hdc device context
+ * @param lpPoints array of series of points
+ * @param lpPolyCounts array of number of points in each series
+ * @param nCount count of number of points in lpPolyCounts
+ * @return
+ */
+int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount)
+{
+ return 1;
+}
+
+/**
+ * Draw a rectangle
+ * @param hdc device context
+ * @param nLeftRect x1
+ * @param nTopRect y1
+ * @param nRightRect x2
+ * @param nBottomRect y2
+ * @return
+ */
+int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
+{
+ return 1;
+}
--- /dev/null
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * GDI Shape Functions
+ *
+ * Copyright 2010-2011 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 __GDI_SHAPE_H
+#define __GDI_SHAPE_H
+
+#include "gdi.h"
+
+int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
+int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
+int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount);
+int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount);
+int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
+
+typedef int (*pFillRect)(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
+
+#endif /* __GDI_SHAPE_H */