server/shadow: Fix alpha pointer message so that it allows pixel with both 'xor' and 'and'.
Integrate idea from @bmiklautz: make convert_alpha_pointer_data function as common
This commit is contained in:
parent
457413727f
commit
2673a77905
@ -261,6 +261,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry);
|
||||
FREERDP_API int shadow_subsystem_pointer_convert_alpha_pointer_data(BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor);
|
||||
|
||||
FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv);
|
||||
FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status);
|
||||
|
@ -397,89 +397,6 @@ int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem)
|
||||
return shadow_client_boardcast_msg(subsystem->server, NULL, msgId, (SHADOW_MSG_OUT*) msg, NULL) ? 1 : -1;
|
||||
}
|
||||
|
||||
static int x11_shadow_pointer_convert_alpha_pointer_data(BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor)
|
||||
{
|
||||
UINT32 x, y;
|
||||
BYTE* pSrc8;
|
||||
BYTE* pDst8;
|
||||
int xorStep;
|
||||
int andStep;
|
||||
UINT32 andBit;
|
||||
BYTE* andBits;
|
||||
UINT32 andPixel;
|
||||
BYTE A, R, G, B;
|
||||
|
||||
xorStep = (width * 3);
|
||||
xorStep += (xorStep % 2);
|
||||
|
||||
andStep = ((width + 7) / 8);
|
||||
andStep += (andStep % 2);
|
||||
|
||||
pointerColor->lengthXorMask = height * xorStep;
|
||||
pointerColor->xorMaskData = (BYTE*) calloc(1, pointerColor->lengthXorMask);
|
||||
|
||||
if (!pointerColor->xorMaskData)
|
||||
return -1;
|
||||
|
||||
pointerColor->lengthAndMask = height * andStep;
|
||||
pointerColor->andMaskData = (BYTE*) calloc(1, pointerColor->lengthAndMask);
|
||||
|
||||
if (!pointerColor->andMaskData)
|
||||
{
|
||||
free(pointerColor->xorMaskData);
|
||||
pointerColor->xorMaskData = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
pSrc8 = &pixels[(width * 4) * (height - 1 - y)];
|
||||
pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
|
||||
|
||||
andBit = 0x80;
|
||||
andBits = &(pointerColor->andMaskData[andStep * y]);
|
||||
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
B = *pSrc8++;
|
||||
G = *pSrc8++;
|
||||
R = *pSrc8++;
|
||||
A = *pSrc8++;
|
||||
|
||||
andPixel = 0;
|
||||
|
||||
if (A < 64)
|
||||
A = 0; /* pixel cannot be partially transparent */
|
||||
|
||||
if (!A)
|
||||
{
|
||||
/* transparent pixel: XOR = black, AND = 1 */
|
||||
andPixel = 1;
|
||||
B = G = R = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (premultiplied)
|
||||
{
|
||||
B = (B * 0xFF ) / A;
|
||||
G = (G * 0xFF ) / A;
|
||||
R = (R * 0xFF ) / A;
|
||||
}
|
||||
}
|
||||
|
||||
*pDst8++ = B;
|
||||
*pDst8++ = G;
|
||||
*pDst8++ = R;
|
||||
|
||||
if (andPixel) *andBits |= andBit;
|
||||
if (!(andBit >>= 1)) { andBits++; andBit = 0x80; }
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem)
|
||||
{
|
||||
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* msg;
|
||||
@ -495,7 +412,7 @@ int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem)
|
||||
msg->width = subsystem->cursorWidth;
|
||||
msg->height = subsystem->cursorHeight;
|
||||
|
||||
if (x11_shadow_pointer_convert_alpha_pointer_data(subsystem->cursorPixels, TRUE,
|
||||
if (shadow_subsystem_pointer_convert_alpha_pointer_data(subsystem->cursorPixels, TRUE,
|
||||
msg->width, msg->height, msg) < 0)
|
||||
{
|
||||
free (msg);
|
||||
|
@ -182,3 +182,92 @@ int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
|
||||
|
||||
return numMonitors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common function for subsystem implementation.
|
||||
* This function convert 32bit ARGB format pixels to xormask data
|
||||
* and andmask data and fill into SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
|
||||
* Caller should free the andMaskData and xorMaskData later.
|
||||
*/
|
||||
int shadow_subsystem_pointer_convert_alpha_pointer_data(BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor)
|
||||
{
|
||||
UINT32 x, y;
|
||||
BYTE* pSrc8;
|
||||
BYTE* pDst8;
|
||||
int xorStep;
|
||||
int andStep;
|
||||
UINT32 andBit;
|
||||
BYTE* andBits;
|
||||
UINT32 andPixel;
|
||||
BYTE A, R, G, B;
|
||||
|
||||
xorStep = (width * 3);
|
||||
xorStep += (xorStep % 2);
|
||||
|
||||
andStep = ((width + 7) / 8);
|
||||
andStep += (andStep % 2);
|
||||
|
||||
pointerColor->lengthXorMask = height * xorStep;
|
||||
pointerColor->xorMaskData = (BYTE*) calloc(1, pointerColor->lengthXorMask);
|
||||
|
||||
if (!pointerColor->xorMaskData)
|
||||
return -1;
|
||||
|
||||
pointerColor->lengthAndMask = height * andStep;
|
||||
pointerColor->andMaskData = (BYTE*) calloc(1, pointerColor->lengthAndMask);
|
||||
|
||||
if (!pointerColor->andMaskData)
|
||||
{
|
||||
free(pointerColor->xorMaskData);
|
||||
pointerColor->xorMaskData = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
pSrc8 = &pixels[(width * 4) * (height - 1 - y)];
|
||||
pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
|
||||
|
||||
andBit = 0x80;
|
||||
andBits = &(pointerColor->andMaskData[andStep * y]);
|
||||
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
B = *pSrc8++;
|
||||
G = *pSrc8++;
|
||||
R = *pSrc8++;
|
||||
A = *pSrc8++;
|
||||
|
||||
andPixel = 0;
|
||||
|
||||
if (A < 64)
|
||||
A = 0; /* pixel cannot be partially transparent */
|
||||
|
||||
if (!A)
|
||||
{
|
||||
/* transparent pixel: XOR = black, AND = 1 */
|
||||
andPixel = 1;
|
||||
B = G = R = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (premultiplied)
|
||||
{
|
||||
B = (B * 0xFF ) / A;
|
||||
G = (G * 0xFF ) / A;
|
||||
R = (R * 0xFF ) / A;
|
||||
}
|
||||
}
|
||||
|
||||
*pDst8++ = B;
|
||||
*pDst8++ = G;
|
||||
*pDst8++ = R;
|
||||
|
||||
if (andPixel) *andBits |= andBit;
|
||||
if (!(andBit >>= 1)) { andBits++; andBit = 0x80; }
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user