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.
|
* two less significant bits of the first byte.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FASTPATH_MAX_PACKET_SIZE 0x7FFF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a Fast-Path packet header.\n
|
* Read a Fast-Path packet header.\n
|
||||||
* @param s stream
|
* @param s stream
|
||||||
@ -410,18 +412,19 @@ boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
|
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
||||||
{
|
{
|
||||||
STREAM* s;
|
STREAM* s;
|
||||||
s = transport_send_stream_init(fastpath->rdp->transport, 127);
|
s = transport_send_stream_init(fastpath->rdp->transport, 127);
|
||||||
stream_seek(s, 2); /* fpInputHeader and length1 */
|
stream_seek(s, 2); /* fpInputHeader and length1 */
|
||||||
/* length2 is not necessary since input PDU should not exceed 127 bytes */
|
/* length2 is not necessary since input PDU should not exceed 127 bytes */
|
||||||
|
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||||
return s;
|
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);
|
length = stream_get_length(s);
|
||||||
if (length > 127)
|
if (length > 127)
|
||||||
@ -431,7 +434,7 @@ boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_set_pos(s, 0);
|
stream_set_pos(s, 0);
|
||||||
stream_write_uint8(s, (numberEvents << 2));
|
stream_write_uint8(s, (1 << 2));
|
||||||
stream_write_uint8(s, length);
|
stream_write_uint8(s, length);
|
||||||
|
|
||||||
stream_set_pos(s, length);
|
stream_set_pos(s, length);
|
||||||
@ -441,17 +444,87 @@ boolean fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath)
|
||||||
{
|
{
|
||||||
STREAM* s;
|
STREAM* s;
|
||||||
s = fastpath_pdu_init(fastpath);
|
s = transport_send_stream_init(fastpath->rdp->transport, FASTPATH_MAX_PACKET_SIZE);
|
||||||
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
stream_seek(s, 3); /* fpOutputHeader, length1 and length2 */
|
||||||
return s;
|
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)
|
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_updates(rdpFastPath* fastpath, STREAM* s);
|
||||||
boolean fastpath_recv_inputs(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);
|
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode);
|
||||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
|
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);
|
rdpFastPath* fastpath_new(rdpRdp* rdp);
|
||||||
void fastpath_free(rdpFastPath* fastpath);
|
void fastpath_free(rdpFastPath* fastpath);
|
||||||
|
|
||||||
|
@ -84,3 +84,35 @@ boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
|
|||||||
return True;
|
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);
|
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 */
|
#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)
|
void update_register_server_callbacks(rdpUpdate* update)
|
||||||
{
|
{
|
||||||
update->BeginPaint = update_begin_paint;
|
update->BeginPaint = update_begin_paint;
|
||||||
update->EndPaint = update_end_paint;
|
update->EndPaint = update_end_paint;
|
||||||
|
update->SurfaceBits = update_send_surface_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpUpdate* update_new(rdpRdp* rdp)
|
rdpUpdate* update_new(rdpRdp* rdp)
|
||||||
|
Loading…
Reference in New Issue
Block a user