20#include <freerdp/config.h>
24#include <freerdp/codecs.h>
25#include <freerdp/log.h>
28#include "wf_graphics.h"
30#define TAG CLIENT_TAG("windows")
32HBITMAP 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);
69wfBitmap* wf_image_new(wfContext* wfc, UINT32 width, UINT32 height, UINT32 format,
const BYTE* data)
74 WLog_ERR(TAG,
"malloc failed for wfBitmap");
78 HDC hdc = GetDC(NULL);
79 image->hdc = CreateCompatibleDC(hdc);
80 image->bitmap = wf_create_dib(wfc, width, height, format, data, &(image->pdata));
81 image->org_bitmap = (HBITMAP)SelectObject(image->hdc, image->bitmap);
90 SelectObject(image->hdc, image->org_bitmap);
91 DeleteObject(image->bitmap);
99static BOOL wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
102 wfContext* wfc = (wfContext*)context;
105 if (!context || !bitmap)
110 wf_bitmap->hdc = CreateCompatibleDC(hdc);
113 wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height);
116 wf_create_dib(wfc, bitmap->width, bitmap->height, bitmap->format, bitmap->data, NULL);
118 wf_bitmap->org_bitmap = (HBITMAP)SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap);
119 ReleaseDC(NULL, hdc);
123static void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
129 SelectObject(wf_bitmap->hdc, wf_bitmap->org_bitmap);
130 DeleteObject(wf_bitmap->bitmap);
131 DeleteDC(wf_bitmap->hdc);
133 winpr_aligned_free(wf_bitmap->_bitmap.data);
134 wf_bitmap->_bitmap.data = NULL;
138static BOOL wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
141 UINT32 width, height;
142 wfContext* wfc = (wfContext*)context;
145 if (!context || !bitmap)
148 width = bitmap->right - bitmap->left + 1;
149 height = bitmap->bottom - bitmap->top + 1;
150 rc = BitBlt(wfc->primary->hdc, bitmap->left, bitmap->top, width, height, wf_bitmap->hdc, 0, 0,
152 wf_invalidate_region(wfc, bitmap->left, bitmap->top, width, height);
156static BOOL wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
158 wfContext* wfc = (wfContext*)context;
160 rdpGdi* gdi = context->gdi;
166 wfc->drawing = wfc->primary;
177static BOOL flip_bitmap(
const BYTE* src, BYTE* dst, UINT32 scanline, UINT32 nHeight)
179 BYTE* bottomLine = dst + scanline * (nHeight - 1);
181 for (UINT32 x = 0; x < nHeight; x++)
183 memcpy(bottomLine, src, scanline);
185 bottomLine -= scanline;
191static BOOL wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
198 if (!context || !pointer)
207 info.xHotspot = pointer->xPos;
208 info.yHotspot = pointer->yPos;
210 if (pointer->xorBpp == 1)
214 if ((pointer->lengthAndMask > 0) || (pointer->lengthXorMask > 0))
217 (BYTE*)winpr_aligned_malloc(pointer->lengthAndMask + pointer->lengthXorMask, 16);
223 CopyMemory(pdata, pointer->andMaskData, pointer->lengthAndMask);
224 CopyMemory(pdata + pointer->lengthAndMask, pointer->xorMaskData, pointer->lengthXorMask);
225 info.hbmMask = CreateBitmap(pointer->width, pointer->height * 2, 1, 1, pdata);
226 winpr_aligned_free(pdata);
227 info.hbmColor = NULL;
234 if (pointer->lengthAndMask > 0)
236 pdata = (BYTE*)winpr_aligned_malloc(pointer->lengthAndMask, 16);
240 flip_bitmap(pointer->andMaskData, pdata, (pointer->width + 7) / 8, pointer->height);
243 info.hbmMask = CreateBitmap(pointer->width, pointer->height, 1, 1, pdata);
244 winpr_aligned_free(pdata);
247 srcFormat = gdi_get_pixel_format(pointer->xorBpp);
252 info.hbmColor = wf_create_dib((wfContext*)context, pointer->width, pointer->height,
253 gdi->dstFormat, NULL, &pdata);
258 if (!freerdp_image_copy_from_pointer_data(
259 pdata, gdi->dstFormat, 0, 0, 0, pointer->width, pointer->height,
260 pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData,
261 pointer->lengthAndMask, pointer->xorBpp, &gdi->palette))
267 hCur = CreateIconIndirect(&info);
273 DeleteObject(info.hbmMask);
276 DeleteObject(info.hbmColor);
281static void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
285 if (!context || !pointer)
294static BOOL wf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
297 wfContext* wfc = (wfContext*)context;
299 if (!context || !pointer)
313static BOOL wf_Pointer_SetNull(rdpContext* context)
321static BOOL wf_Pointer_SetDefault(rdpContext* context)
329static BOOL wf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
337BOOL wf_register_pointer(rdpGraphics* graphics)
340 rdpPointer pointer = { 0 };
345 wfc = (wfContext*)graphics->context;
347 pointer.New = wf_Pointer_New;
348 pointer.Free = wf_Pointer_Free;
349 pointer.Set = wf_Pointer_Set;
350 pointer.SetNull = wf_Pointer_SetNull;
351 pointer.SetDefault = wf_Pointer_SetDefault;
352 pointer.SetPosition = wf_Pointer_SetPosition;
353 graphics_register_pointer(graphics, &pointer);
359BOOL wf_register_graphics(rdpGraphics* graphics)
368 wfc = (wfContext*)graphics->context;
369 bitmap = *graphics->Bitmap_Prototype;
371 bitmap.New = wf_Bitmap_New;
372 bitmap.Free = wf_Bitmap_Free;
373 bitmap.Paint = wf_Bitmap_Paint;
374 bitmap.SetSurface = wf_Bitmap_SetSurface;
375 graphics_register_bitmap(graphics, &bitmap);
376 glyph = *graphics->Glyph_Prototype;
377 graphics_register_glyph(graphics, &glyph);