From 3477f34479178920e796ef9cc5784cea95520519 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Sat, 26 May 2012 21:34:09 +0800 Subject: [PATCH] server: support RefreshRect and SuppressOutput. --- libfreerdp-core/capabilities.c | 7 ------ libfreerdp-core/freerdp.c | 2 ++ libfreerdp-core/peer.c | 10 ++++++++ libfreerdp-core/update.c | 43 ++++++++++++++++++++++++++++++++-- libfreerdp-core/update.h | 4 ++++ server/test/tfreerdp.c | 29 +++++++++++++++++++++++ 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 67bd5f487..fe1681e88 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -165,13 +165,6 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) if (settings->salted_checksum) extraFlags |= ENC_SALTED_CHECKSUM; - if (settings->server_mode) - { - /* not yet supported server-side */ - settings->refresh_rect = false; - settings->suppress_output = false; - } - stream_write_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */ stream_write_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */ stream_write_uint16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c index 80d01d0c7..a30602d2b 100644 --- a/libfreerdp-core/freerdp.c +++ b/libfreerdp-core/freerdp.c @@ -225,6 +225,8 @@ void freerdp_context_new(freerdp* instance) instance->input->context = instance->context; + update_register_client_callbacks(rdp->update); + IFCALL(instance->ContextNew, instance, instance->context); } diff --git a/libfreerdp-core/peer.c b/libfreerdp-core/peer.c index 4e2452746..1513eead4 100644 --- a/libfreerdp-core/peer.c +++ b/libfreerdp-core/peer.c @@ -126,6 +126,16 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s) stream_read_uint32(s, client->ack_frame_id); break; + case DATA_PDU_TYPE_REFRESH_RECT: + if (!update_read_refresh_rect(client->update, s)) + return false; + break; + + case DATA_PDU_TYPE_SUPPRESS_OUTPUT: + if (!update_read_suppress_output(client->update, s)) + return false; + break; + default: printf("Data PDU type %d\n", type); break; diff --git a/libfreerdp-core/update.c b/libfreerdp-core/update.c index fa885780c..297541668 100644 --- a/libfreerdp-core/update.c +++ b/libfreerdp-core/update.c @@ -518,14 +518,47 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s); } +boolean update_read_refresh_rect(rdpUpdate* update, STREAM* s) +{ + uint8 numberOfAreas; + + if (stream_get_left(s) < 4) + return false; + + stream_read_uint8(s, numberOfAreas); + stream_seek(s, 3); /* pad3Octects */ + if (stream_get_left(s) < numberOfAreas * 8) + return false; + + IFCALL(update->RefreshRect, update->context, numberOfAreas, (RECTANGLE_16*) stream_get_tail(s)); + + return true; +} + +boolean update_read_suppress_output(rdpUpdate* update, STREAM* s) +{ + uint8 allowDisplayUpdates; + + if (stream_get_left(s) < 4) + return false; + + stream_read_uint8(s, allowDisplayUpdates); + stream_seek(s, 3); /* pad3Octects */ + if (allowDisplayUpdates > 0 && stream_get_left(s) < 8) + return false; + + IFCALL(update->SuppressOutput, update->context, allowDisplayUpdates, + allowDisplayUpdates > 0 ? (RECTANGLE_16*) stream_get_tail(s) : NULL); + + return true; +} + void update_register_server_callbacks(rdpUpdate* update) { update->BeginPaint = update_begin_paint; update->EndPaint = update_end_paint; update->Synchronize = update_send_synchronize; update->DesktopResize = update_send_desktop_resize; - update->RefreshRect = update_send_refresh_rect; - update->SuppressOutput = update_send_suppress_output; update->SurfaceBits = update_send_surface_bits; update->SurfaceFrameMarker = update_send_surface_frame_marker; update->SurfaceCommand = update_send_surface_command; @@ -536,6 +569,12 @@ void update_register_server_callbacks(rdpUpdate* update) update->pointer->PointerCached = update_send_pointer_cached; } +void update_register_client_callbacks(rdpUpdate* update) +{ + update->RefreshRect = update_send_refresh_rect; + update->SuppressOutput = update_send_suppress_output; +} + rdpUpdate* update_new(rdpRdp* rdp) { rdpUpdate* update; diff --git a/libfreerdp-core/update.h b/libfreerdp-core/update.h index 6c0eccf8a..0a69cc8f5 100644 --- a/libfreerdp-core/update.h +++ b/libfreerdp-core/update.h @@ -52,6 +52,10 @@ void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color); void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new); void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached); +boolean update_read_refresh_rect(rdpUpdate* update, STREAM* s); +boolean update_read_suppress_output(rdpUpdate* update, STREAM* s); + void update_register_server_callbacks(rdpUpdate* update); +void update_register_client_callbacks(rdpUpdate* update); #endif /* __UPDATE_H */ diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c index b02c1ecaf..cb402a03e 100644 --- a/server/test/tfreerdp.c +++ b/server/test/tfreerdp.c @@ -580,6 +580,30 @@ void tf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint1 printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y); } +static void tf_peer_refresh_rect(rdpContext* context, uint8 count, RECTANGLE_16* areas) +{ + uint8 i; + + printf("Client requested to refresh:\n"); + + for (i = 0; i < count; i++) + { + printf(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); + } +} + +static void tf_peer_suppress_output(rdpContext* context, uint8 allow, RECTANGLE_16* area) +{ + if (allow > 0) + { + printf("Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom); + } + else + { + printf("Client minimized and suppress output.\n"); + } +} + static void* test_peer_mainloop(void* arg) { int i; @@ -600,6 +624,8 @@ static void* test_peer_mainloop(void* arg) client->settings->privatekey_file = xstrdup("server.key"); client->settings->nla_security = false; client->settings->rfx_codec = true; + client->settings->suppress_output = true; + client->settings->refresh_rect = true; client->PostConnect = tf_peer_post_connect; client->Activate = tf_peer_activate; @@ -610,6 +636,9 @@ static void* test_peer_mainloop(void* arg) client->input->MouseEvent = tf_peer_mouse_event; client->input->ExtendedMouseEvent = tf_peer_extended_mouse_event; + client->update->RefreshRect = tf_peer_refresh_rect; + client->update->SuppressOutput = tf_peer_suppress_output; + client->Initialize(client); context = (testPeerContext*) client->context;