server: add SurfaceCmds update.

This commit is contained in:
Vic Lee 2011-08-23 23:28:28 +08:00
parent a5e251a5b2
commit c79c587ca9
5 changed files with 130 additions and 12 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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)