libfreerdp-gdi: initial commit
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 30 Jun 2011 20:17:55 +0000 (16:17 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 30 Jun 2011 20:17:55 +0000 (16:17 -0400)
27 files changed:
libfreerdp-gdi/gdi.h [new file with mode: 0644]
libfreerdp-gdi/gdi_16bpp.c [new file with mode: 0644]
libfreerdp-gdi/gdi_16bpp.h [new file with mode: 0644]
libfreerdp-gdi/gdi_32bpp.c [new file with mode: 0644]
libfreerdp-gdi/gdi_32bpp.h [new file with mode: 0644]
libfreerdp-gdi/gdi_8bpp.c [new file with mode: 0644]
libfreerdp-gdi/gdi_8bpp.h [new file with mode: 0644]
libfreerdp-gdi/gdi_bitmap.c [new file with mode: 0644]
libfreerdp-gdi/gdi_bitmap.h [new file with mode: 0644]
libfreerdp-gdi/gdi_brush.c [new file with mode: 0644]
libfreerdp-gdi/gdi_brush.h [new file with mode: 0644]
libfreerdp-gdi/gdi_clipping.c [new file with mode: 0644]
libfreerdp-gdi/gdi_clipping.h [new file with mode: 0644]
libfreerdp-gdi/gdi_dc.c [new file with mode: 0644]
libfreerdp-gdi/gdi_dc.h [new file with mode: 0644]
libfreerdp-gdi/gdi_drawing.c [new file with mode: 0644]
libfreerdp-gdi/gdi_drawing.h [new file with mode: 0644]
libfreerdp-gdi/gdi_line.c [new file with mode: 0644]
libfreerdp-gdi/gdi_line.h [new file with mode: 0644]
libfreerdp-gdi/gdi_palette.c [new file with mode: 0644]
libfreerdp-gdi/gdi_palette.h [new file with mode: 0644]
libfreerdp-gdi/gdi_pen.c [new file with mode: 0644]
libfreerdp-gdi/gdi_pen.h [new file with mode: 0644]
libfreerdp-gdi/gdi_region.c [new file with mode: 0644]
libfreerdp-gdi/gdi_region.h [new file with mode: 0644]
libfreerdp-gdi/gdi_shape.c [new file with mode: 0644]
libfreerdp-gdi/gdi_shape.h [new file with mode: 0644]

diff --git a/libfreerdp-gdi/gdi.h b/libfreerdp-gdi/gdi.h
new file mode 100644 (file)
index 0000000..472077e
--- /dev/null
@@ -0,0 +1,273 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_16bpp.c b/libfreerdp-gdi/gdi_16bpp.c
new file mode 100644 (file)
index 0000000..b4d07b5
--- /dev/null
@@ -0,0 +1,1044 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_16bpp.h b/libfreerdp-gdi/gdi_16bpp.h
new file mode 100644 (file)
index 0000000..5f51f1c
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * 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);
diff --git a/libfreerdp-gdi/gdi_32bpp.c b/libfreerdp-gdi/gdi_32bpp.c
new file mode 100644 (file)
index 0000000..0888386
--- /dev/null
@@ -0,0 +1,1117 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_32bpp.h b/libfreerdp-gdi/gdi_32bpp.h
new file mode 100644 (file)
index 0000000..3923a9f
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * 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);
diff --git a/libfreerdp-gdi/gdi_8bpp.c b/libfreerdp-gdi/gdi_8bpp.c
new file mode 100644 (file)
index 0000000..704dbaf
--- /dev/null
@@ -0,0 +1,875 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_8bpp.h b/libfreerdp-gdi/gdi_8bpp.h
new file mode 100644 (file)
index 0000000..6ee6e4d
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * 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);
diff --git a/libfreerdp-gdi/gdi_bitmap.c b/libfreerdp-gdi/gdi_bitmap.c
new file mode 100644 (file)
index 0000000..831c9a5
--- /dev/null
@@ -0,0 +1,189 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_bitmap.h b/libfreerdp-gdi/gdi_bitmap.h
new file mode 100644 (file)
index 0000000..ba9272b
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_brush.c b/libfreerdp-gdi/gdi_brush.c
new file mode 100644 (file)
index 0000000..23fe99c
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_brush.h b/libfreerdp-gdi/gdi_brush.h
new file mode 100644 (file)
index 0000000..26d8d7d
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_clipping.c b/libfreerdp-gdi/gdi_clipping.c
new file mode 100644 (file)
index 0000000..6691680
--- /dev/null
@@ -0,0 +1,172 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_clipping.h b/libfreerdp-gdi/gdi_clipping.h
new file mode 100644 (file)
index 0000000..fc44771
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_dc.c b/libfreerdp-gdi/gdi_dc.c
new file mode 100644 (file)
index 0000000..a205f8d
--- /dev/null
@@ -0,0 +1,190 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_dc.h b/libfreerdp-gdi/gdi_dc.h
new file mode 100644 (file)
index 0000000..b457305
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_drawing.c b/libfreerdp-gdi/gdi_drawing.c
new file mode 100644 (file)
index 0000000..56b71f7
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_drawing.h b/libfreerdp-gdi/gdi_drawing.h
new file mode 100644 (file)
index 0000000..cc58cce
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_line.c b/libfreerdp-gdi/gdi_line.c
new file mode 100644 (file)
index 0000000..1eb79ee
--- /dev/null
@@ -0,0 +1,151 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_line.h b/libfreerdp-gdi/gdi_line.h
new file mode 100644 (file)
index 0000000..51e4691
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_palette.c b/libfreerdp-gdi/gdi_palette.c
new file mode 100644 (file)
index 0000000..032b2ef
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_palette.h b/libfreerdp-gdi/gdi_palette.h
new file mode 100644 (file)
index 0000000..0bfba44
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_pen.c b/libfreerdp-gdi/gdi_pen.c
new file mode 100644 (file)
index 0000000..01a7b73
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_pen.h b/libfreerdp-gdi/gdi_pen.h
new file mode 100644 (file)
index 0000000..3978d2b
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_region.c b/libfreerdp-gdi/gdi_region.c
new file mode 100644 (file)
index 0000000..191b169
--- /dev/null
@@ -0,0 +1,422 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_region.h b/libfreerdp-gdi/gdi_region.h
new file mode 100644 (file)
index 0000000..61f8ed4
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * 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 */
diff --git a/libfreerdp-gdi/gdi_shape.c b/libfreerdp-gdi/gdi_shape.c
new file mode 100644 (file)
index 0000000..5456312
--- /dev/null
@@ -0,0 +1,240 @@
+/**
+ * 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;
+}
diff --git a/libfreerdp-gdi/gdi_shape.h b/libfreerdp-gdi/gdi_shape.h
new file mode 100644 (file)
index 0000000..7329734
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * 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 */