rdp协议中会把图像和鼠标样式分开发送,这样做的好处是,避免鼠标与图像一起绘制时会导致鼠标严重延迟,freerdp中可以很容易的获取鼠标样式的bitmap,但是在windows中,需要绘制ico就需要重建icoinfo文件,相对复杂,不是本文关心的内容,因此本文只介绍如何获取rbga内容。
入口函数
创建一个保存鼠标样式的数据类型,node_register_pointer函数需要在freerdp_connect函数中首先调用,
typedef struct _NodePointer
{
rdpPointer pointer;
byte * buffer;
int width;
int height;
}NodePointer;
BOOL node_register_pointer(rdpGraphics* graphics)
{
rdpPointer pointer;
if (!graphics)
return FALSE;
ZeroMemory(&pointer, sizeof(rdpPointer));
pointer.size = sizeof(NodePointer);
pointer.New = reinterpret_cast<pPointer_New>(node_Pointer_New);
pointer.Free = reinterpret_cast<pPointer_Free>(node_Pointer_Free);
pointer.Set = reinterpret_cast<pPointer_Set>(node_Pointer_Set);
graphics_register_pointer(graphics, &pointer);
return TRUE;
}
Pointer回调
核心代码在于freerdp_image_copy_from_pointer_data函数,可以通过xorMaskData和andMaskData数据得到rgba数据,当然也可以修改PIXEL_FORMAT_RGBA32为PIXEL_FORMAT_GBRA32来调整rgba的顺序。
BOOL node_Pointer_New(rdpContext* context, const rdpPointer* pointer)
{
int size = pointer->height * pointer->width * GetBytesPerPixel(PIXEL_FORMAT_RGBA32);
BYTE* pdata = (BYTE*)_aligned_malloc( size, 16 );
rdpGdi* gdi = context->gdi;
freerdp_image_copy_from_pointer_data(pdata, PIXEL_FORMAT_RGBA32, 0, 0, 0,
pointer->width, pointer->height,
pointer->xorMaskData, pointer->lengthXorMask,
pointer->andMaskData, pointer->lengthAndMask, pointer->xorBpp, &gdi->palette);
((NodePointer *)pointer)->buffer = pdata;
return TRUE;
}
BOOL node_Pointer_Free(rdpContext* context, rdpPointer* pointer)
{
if (!pointer)
return FALSE;
byte * buffer= ((NodePointer*)pointer)->buffer;
if (hCur != 0)
_aligned_free(buffer);
return TRUE;
}
BOOL node_Pointer_Set(rdpContext* context, const rdpPointer* pointer)
{
if (!pointer)
return FALSE;
//客户端直接修改cursor,或者通过网络发送到别的地方
return TRUE;
}