mirror of https://github.com/FreeRDP/FreeRDP
server: add SurfaceCmds update.
This commit is contained in:
parent
a5e251a5b2
commit
c79c587ca9
|
@ -38,6 +38,8 @@
|
|||
* two less significant bits of the first byte.
|
||||
*/
|
||||
|
||||
#define FASTPATH_MAX_PACKET_SIZE 0x7FFF
|
||||
|
||||
/**
|
||||
* Read a Fast-Path packet header.\n
|
||||
* @param s stream
|
||||
|
@ -410,18 +412,19 @@ boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
||||
{
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(fastpath->rdp->transport, 127);
|
||||
stream_seek(s, 2); /* fpInputHeader and length1 */
|
||||
/* length2 is not necessary since input PDU should not exceed 127 bytes */
|
||||
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
return s;
|
||||
}
|
||||
|
||||
boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
int length;
|
||||
uint16 length;
|
||||
|
||||
length = stream_get_length(s);
|
||||
if (length > 127)
|
||||
|
@ -431,7 +434,7 @@ boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
|||
}
|
||||
|
||||
stream_set_pos(s, 0);
|
||||
stream_write_uint8(s, (numberEvents << 2));
|
||||
stream_write_uint8(s, (1 << 2));
|
||||
stream_write_uint8(s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
|
@ -441,17 +444,87 @@ boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
|||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
||||
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath)
|
||||
{
|
||||
STREAM* s;
|
||||
s = fastpath_pdu_init(fastpath);
|
||||
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
s = transport_send_stream_init(fastpath->rdp->transport, FASTPATH_MAX_PACKET_SIZE);
|
||||
stream_seek(s, 3); /* fpOutputHeader, length1 and length2 */
|
||||
return s;
|
||||
}
|
||||
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
return fastpath_send_pdu(fastpath, s, 1);
|
||||
uint16 length;
|
||||
|
||||
length = stream_get_length(s);
|
||||
if (length > FASTPATH_MAX_PACKET_SIZE)
|
||||
{
|
||||
printf("Maximum FastPath Update PDU length is %d\n", FASTPATH_MAX_PACKET_SIZE);
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_set_pos(s, 0);
|
||||
stream_write_uint8(s, 0); /* fpOutputHeader (1 byte) */
|
||||
stream_write_uint8(s, 0x80 | (length >> 8)); /* length1 */
|
||||
stream_write_uint8(s, length & 0xFF); /* length2 */
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(fastpath->rdp->transport, s) < 0)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_send_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
STREAM* s;
|
||||
uint16 size;
|
||||
uint8* bitmapData;
|
||||
uint32 bitmapDataLength;
|
||||
uint16 fragment_size;
|
||||
uint8 fragmentation;
|
||||
int i;
|
||||
int bp, ep;
|
||||
|
||||
bitmapData = cmd->bitmapData;
|
||||
bitmapDataLength = cmd->bitmapDataLength;
|
||||
for (i = 0; bitmapDataLength > 0; i++)
|
||||
{
|
||||
s = fastpath_update_pdu_init(fastpath);
|
||||
|
||||
bp = stream_get_pos(s);
|
||||
stream_seek_uint8(s); /* updateHeader (1 byte) */
|
||||
stream_seek_uint16(s); /* size (2 bytes) */
|
||||
size = 0;
|
||||
|
||||
if (i == 0)
|
||||
size += update_write_surfcmd_surface_bits_header(s, cmd);
|
||||
|
||||
fragment_size = MIN(stream_get_left(s), bitmapDataLength);
|
||||
if (fragment_size == bitmapDataLength)
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT);
|
||||
}
|
||||
size += fragment_size;
|
||||
|
||||
ep = stream_get_pos(s);
|
||||
stream_set_pos(s, bp);
|
||||
stream_write_uint8(s, FASTPATH_UPDATETYPE_SURFCMDS | (fragmentation << 4));
|
||||
stream_write_uint16(s, size);
|
||||
stream_set_pos(s, ep);
|
||||
|
||||
stream_write(s, bitmapData, fragment_size);
|
||||
bitmapData += fragment_size;
|
||||
bitmapDataLength -= fragment_size;
|
||||
|
||||
if (!fastpath_send_update_pdu(fastpath, s))
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
|
|
|
@ -102,12 +102,14 @@ boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s);
|
|||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath);
|
||||
boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents);
|
||||
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode);
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath);
|
||||
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
boolean fastpath_send_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd);
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp);
|
||||
void fastpath_free(rdpFastPath* fastpath);
|
||||
|
||||
|
|
|
@ -84,3 +84,35 @@ boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
int update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
stream_check_size(s, 22);
|
||||
|
||||
stream_write_uint16(s, CMDTYPE_STREAM_SURFACE_BITS);
|
||||
|
||||
stream_write_uint16(s, cmd->destLeft);
|
||||
stream_write_uint16(s, cmd->destTop);
|
||||
stream_write_uint16(s, cmd->destRight);
|
||||
stream_write_uint16(s, cmd->destBottom);
|
||||
stream_write_uint8(s, cmd->bpp);
|
||||
stream_write_uint16(s, 0); /* reserved1, reserved2 */
|
||||
stream_write_uint8(s, cmd->codecID);
|
||||
stream_write_uint16(s, cmd->width);
|
||||
stream_write_uint16(s, cmd->height);
|
||||
stream_write_uint32(s, cmd->bitmapDataLength);
|
||||
|
||||
return 22;
|
||||
}
|
||||
|
||||
int update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId)
|
||||
{
|
||||
stream_check_size(s, 8);
|
||||
|
||||
stream_write_uint16(s, CMDTYPE_FRAME_MARKER);
|
||||
|
||||
stream_write_uint16(s, frameAction);
|
||||
stream_write_uint32(s, frameId);
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,5 +25,8 @@
|
|||
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s);
|
||||
|
||||
int update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
|
||||
int update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId);
|
||||
|
||||
#endif /* __SURFACE */
|
||||
|
||||
|
|
|
@ -225,10 +225,18 @@ static void update_end_paint(rdpUpdate* update)
|
|||
{
|
||||
}
|
||||
|
||||
static void update_send_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)update->rdp;
|
||||
|
||||
fastpath_send_surface_bits(rdp->fastpath, surface_bits_command);
|
||||
}
|
||||
|
||||
void update_register_server_callbacks(rdpUpdate* update)
|
||||
{
|
||||
update->BeginPaint = update_begin_paint;
|
||||
update->EndPaint = update_end_paint;
|
||||
update->SurfaceBits = update_send_surface_bits;
|
||||
}
|
||||
|
||||
rdpUpdate* update_new(rdpRdp* rdp)
|
||||
|
|
Loading…
Reference in New Issue