20 #include <freerdp/config.h>
22 #include <winpr/crt.h>
24 #include <freerdp/codecs.h>
25 #include <freerdp/log.h>
28 #include "wf_graphics.h"
30 #define TAG CLIENT_TAG("windows")
32 HBITMAP wf_create_dib(wfContext* wfc, UINT32 width, UINT32 height, UINT32 srcFormat,
33 const BYTE* data, BYTE** pdata)
40 UINT32 dstFormat = srcFormat;
47 negHeight = (height < 0) ? height : height * (-1);
50 bmi.bmiHeader.biWidth = width;
51 bmi.bmiHeader.biHeight = negHeight;
52 bmi.bmiHeader.biPlanes = 1;
53 bmi.bmiHeader.biBitCount = FreeRDPGetBitsPerPixel(dstFormat);
54 bmi.bmiHeader.biCompression = BI_RGB;
55 bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (
void**)&cdata, NULL, 0);
58 freerdp_image_copy(cdata, dstFormat, 0, 0, 0, width, height, data, srcFormat, 0, 0, 0,
59 &wfc->common.context.gdi->palette, FREERDP_FLIP_NONE);
69 wfBitmap* wf_image_new(wfContext* wfc, UINT32 width, UINT32 height, UINT32 format,
const BYTE* data)
75 image->hdc = CreateCompatibleDC(hdc);
76 image->bitmap = wf_create_dib(wfc, width, height, format, data, &(image->pdata));
77 image->org_bitmap = (HBITMAP)SelectObject(image->hdc, image->bitmap);
86 SelectObject(image->hdc, image->org_bitmap);
87 DeleteObject(image->bitmap);
95 static BOOL wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
98 wfContext* wfc = (wfContext*)context;
101 if (!context || !bitmap)
106 wf_bitmap->hdc = CreateCompatibleDC(hdc);
109 wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height);
112 wf_create_dib(wfc, bitmap->width, bitmap->height, bitmap->format, bitmap->data, NULL);
114 wf_bitmap->org_bitmap = (HBITMAP)SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap);
115 ReleaseDC(NULL, hdc);
119 static void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
125 SelectObject(wf_bitmap->hdc, wf_bitmap->org_bitmap);
126 DeleteObject(wf_bitmap->bitmap);
127 DeleteDC(wf_bitmap->hdc);
129 winpr_aligned_free(wf_bitmap->_bitmap.data);
130 wf_bitmap->_bitmap.data = NULL;
134 static BOOL wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
137 UINT32 width, height;
138 wfContext* wfc = (wfContext*)context;
141 if (!context || !bitmap)
144 width = bitmap->right - bitmap->left + 1;
145 height = bitmap->bottom - bitmap->top + 1;
146 rc = BitBlt(wfc->primary->hdc, bitmap->left, bitmap->top, width, height, wf_bitmap->hdc, 0, 0,
148 wf_invalidate_region(wfc, bitmap->left, bitmap->top, width, height);
152 static BOOL wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
154 wfContext* wfc = (wfContext*)context;
156 rdpGdi* gdi = context->gdi;
162 wfc->drawing = wfc->primary;
173 static BOOL flip_bitmap(
const BYTE* src, BYTE* dst, UINT32 scanline, UINT32 nHeight)
175 BYTE* bottomLine = dst + scanline * (nHeight - 1);
177 for (UINT32 x = 0; x < nHeight; x++)
179 memcpy(bottomLine, src, scanline);
181 bottomLine -= scanline;
187 static BOOL wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
194 if (!context || !pointer)
203 info.xHotspot = pointer->xPos;
204 info.yHotspot = pointer->yPos;
206 if (pointer->xorBpp == 1)
210 if ((pointer->lengthAndMask > 0) || (pointer->lengthXorMask > 0))
213 (BYTE*)winpr_aligned_malloc(pointer->lengthAndMask + pointer->lengthXorMask, 16);
219 CopyMemory(pdata, pointer->andMaskData, pointer->lengthAndMask);
220 CopyMemory(pdata + pointer->lengthAndMask, pointer->xorMaskData, pointer->lengthXorMask);
221 info.hbmMask = CreateBitmap(pointer->width, pointer->height * 2, 1, 1, pdata);
222 winpr_aligned_free(pdata);
223 info.hbmColor = NULL;
230 if (pointer->lengthAndMask > 0)
232 pdata = (BYTE*)winpr_aligned_malloc(pointer->lengthAndMask, 16);
236 flip_bitmap(pointer->andMaskData, pdata, (pointer->width + 7) / 8, pointer->height);
239 info.hbmMask = CreateBitmap(pointer->width, pointer->height, 1, 1, pdata);
240 winpr_aligned_free(pdata);
243 srcFormat = gdi_get_pixel_format(pointer->xorBpp);
248 info.hbmColor = wf_create_dib((wfContext*)context, pointer->width, pointer->height,
249 gdi->dstFormat, NULL, &pdata);
254 if (!freerdp_image_copy_from_pointer_data(
255 pdata, gdi->dstFormat, 0, 0, 0, pointer->width, pointer->height,
256 pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData,
257 pointer->lengthAndMask, pointer->xorBpp, &gdi->palette))
263 hCur = CreateIconIndirect(&info);
269 DeleteObject(info.hbmMask);
272 DeleteObject(info.hbmColor);
277 static void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
281 if (!context || !pointer)
290 static BOOL wf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
293 wfContext* wfc = (wfContext*)context;
295 if (!context || !pointer)
309 static BOOL wf_Pointer_SetNull(rdpContext* context)
317 static BOOL wf_Pointer_SetDefault(rdpContext* context)
325 static BOOL wf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
333 BOOL wf_register_pointer(rdpGraphics* graphics)
336 rdpPointer pointer = { 0 };
341 wfc = (wfContext*)graphics->context;
343 pointer.New = wf_Pointer_New;
344 pointer.Free = wf_Pointer_Free;
345 pointer.Set = wf_Pointer_Set;
346 pointer.SetNull = wf_Pointer_SetNull;
347 pointer.SetDefault = wf_Pointer_SetDefault;
348 pointer.SetPosition = wf_Pointer_SetPosition;
349 graphics_register_pointer(graphics, &pointer);
355 BOOL wf_register_graphics(rdpGraphics* graphics)
364 wfc = (wfContext*)graphics->context;
365 bitmap = *graphics->Bitmap_Prototype;
367 bitmap.New = wf_Bitmap_New;
368 bitmap.Free = wf_Bitmap_Free;
369 bitmap.Paint = wf_Bitmap_Paint;
370 bitmap.SetSurface = wf_Bitmap_SetSurface;
371 graphics_register_bitmap(graphics, &bitmap);
372 glyph = *graphics->Glyph_Prototype;
373 graphics_register_glyph(graphics, &glyph);