From 0e95675da3cc15fb68e7f7c89bfec7b800a5c00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 11 Nov 2011 14:02:59 -0500 Subject: [PATCH] libfreerdp-core: add support for Refresh Rect and Suppress Output PDUs --- channels/rail/rail_orders.c | 6 ++-- include/freerdp/rail.h | 9 ------ include/freerdp/types.h | 9 ++++++ include/freerdp/update.h | 6 ++++ include/freerdp/utils/rail.h | 5 ++- include/freerdp/utils/rect.h | 33 +++++++++++++++++++ libfreerdp-core/capabilities.c | 7 +++++ libfreerdp-core/settings.c | 3 ++ libfreerdp-core/update.c | 46 +++++++++++++++++++++++++++ libfreerdp-core/window.c | 4 +-- libfreerdp-utils/CMakeLists.txt | 1 + libfreerdp-utils/rect.c | 56 +++++++++++++++++++++++++++++++++ 12 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 include/freerdp/utils/rect.h create mode 100644 libfreerdp-utils/rect.c diff --git a/channels/rail/rail_orders.c b/channels/rail/rail_orders.c index 10bc65af3..2ac9dd4de 100644 --- a/channels/rail/rail_orders.c +++ b/channels/rail/rail_orders.c @@ -249,15 +249,15 @@ void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam) break; case SPI_SET_WORK_AREA: - rail_write_rectangle_16(s, &sysparam->workArea); + freerdp_write_rectangle_16(s, &sysparam->workArea); break; case SPI_DISPLAY_CHANGE: - rail_write_rectangle_16(s, &sysparam->displayChange); + freerdp_write_rectangle_16(s, &sysparam->displayChange); break; case SPI_TASKBAR_POS: - rail_write_rectangle_16(s, &sysparam->taskbarPos); + freerdp_write_rectangle_16(s, &sysparam->taskbarPos); break; case SPI_SET_HIGH_CONTRAST: diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 915cfcbc0..840e7f0c6 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -157,15 +157,6 @@ struct _UNICODE_STRING }; typedef struct _UNICODE_STRING UNICODE_STRING; -struct _RECTANGLE_16 -{ - uint16 left; - uint16 top; - uint16 right; - uint16 bottom; -}; -typedef struct _RECTANGLE_16 RECTANGLE_16; - struct _HIGH_CONTRAST { uint32 flags; diff --git a/include/freerdp/types.h b/include/freerdp/types.h index 6846c7461..8d4fc177d 100644 --- a/include/freerdp/types.h +++ b/include/freerdp/types.h @@ -81,6 +81,15 @@ struct _RDP_RECT }; typedef struct _RDP_RECT RDP_RECT; +struct _RECTANGLE_16 +{ + uint16 left; + uint16 top; + uint16 right; + uint16 bottom; +}; +typedef struct _RECTANGLE_16 RECTANGLE_16; + /* Plugin events */ typedef struct _RDP_EVENT RDP_EVENT; diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 0b266cc58..9937c80fc 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -1132,6 +1132,9 @@ typedef void (*pNotifyIconDelete)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInf typedef void (*pMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop); typedef void (*pNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); +typedef void (*pRefreshRect)(rdpUpdate* update, uint8 count, RECTANGLE_16* areas); +typedef void (*pSuppressOutput)(rdpUpdate* update, uint8 allow, RECTANGLE_16* area); + typedef void (*pSurfaceBits)(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command); typedef void (*pSurfaceCommand)(rdpUpdate* update, STREAM* s); @@ -1208,6 +1211,9 @@ struct rdp_update pMonitoredDesktop MonitoredDesktop; pNonMonitoredDesktop NonMonitoredDesktop; + pRefreshRect RefreshRect; + pSuppressOutput SuppressOutput; + pSurfaceBits SurfaceBits; pSurfaceCommand SurfaceCommand; diff --git a/include/freerdp/utils/rail.h b/include/freerdp/utils/rail.h index 5a0bebf79..1b95810f0 100644 --- a/include/freerdp/utils/rail.h +++ b/include/freerdp/utils/rail.h @@ -22,17 +22,16 @@ #include #include +#include #include -#define RAIL_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) +#define RAIL_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) FREERDP_API void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString); FREERDP_API void rail_unicode_string_free(UNICODE_STRING* unicode_string); FREERDP_API void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); FREERDP_API void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); FREERDP_API void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string); -FREERDP_API void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); -FREERDP_API void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); FREERDP_API void* rail_clone_order(uint32 event_type, void* order); FREERDP_API void rail_free_cloned_order(uint32 event_type, void* order); diff --git a/include/freerdp/utils/rect.h b/include/freerdp/utils/rect.h new file mode 100644 index 000000000..530dfbb1e --- /dev/null +++ b/include/freerdp/utils/rect.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Rectangle Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RECT_UTILS_H +#define __RECT_UTILS_H + +#include +#include +#include + +FREERDP_API void freerdp_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); +FREERDP_API void freerdp_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); + +FREERDP_API RECTANGLE_16* freerdp_rectangle_16_new(uint16 left, uint16 top, uint16 right, uint16 bottom); +FREERDP_API void freerdp_rectangle_16_free(RECTANGLE_16* rectangle_16); + +#endif /* __RECT_UTILS_H */ diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index b6e9819f6..d627f0f08 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -146,6 +146,13 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) if (settings->fastpath_output) extraFlags |= FASTPATH_OUTPUT_SUPPORTED; + if (settings->server_mode) + { + /* not yet supported server-side */ + settings->refresh_rect = False; + settings->suppress_output = False; + } + stream_write_uint16(s, 0); /* osMajorType (2 bytes) */ stream_write_uint16(s, 0); /* osMinorType (2 bytes) */ stream_write_uint16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c index 72f50d3af..2ace958f0 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp-core/settings.c @@ -107,6 +107,9 @@ rdpSettings* settings_new(void* instance) settings->bitmap_cache = True; settings->persistent_bitmap_cache = False; + settings->refresh_rect = True; + settings->suppress_output = True; + settings->glyphSupportLevel = GLYPH_SUPPORT_NONE; settings->glyphCache[0].cacheEntries = 254; settings->glyphCache[0].cacheMaximumCellSize = 4; diff --git a/libfreerdp-core/update.c b/libfreerdp-core/update.c index 794426ef7..67e0ddaa4 100644 --- a/libfreerdp-core/update.c +++ b/libfreerdp-core/update.c @@ -19,6 +19,7 @@ #include "update.h" #include "surface.h" +#include #include uint8 UPDATE_TYPE_STRINGS[][32] = @@ -332,6 +333,49 @@ static void update_begin_paint(rdpUpdate* update) static void update_end_paint(rdpUpdate* update) { + +} + +static void update_write_refresh_rect(STREAM* s, uint8 count, RECTANGLE_16* areas) +{ + int i; + + stream_write_uint8(s, count); /* numberOfAreas (1 byte) */ + stream_seek(s, 3); /* pad3Octets (3 bytes) */ + + for (i = 0; i < count; i++) + freerdp_write_rectangle_16(s, &areas[i]); +} + +static void update_send_refresh_rect(rdpUpdate* update, uint8 count, RECTANGLE_16* areas) +{ + STREAM* s; + rdpRdp* rdp = update->context->rdp; + + s = rdp_data_pdu_init(rdp); + update_write_refresh_rect(s, count, areas); + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id); +} + +static void update_write_suppress_output(STREAM* s, uint8 allow, RECTANGLE_16* area) +{ + stream_write_uint8(s, allow); /* allowDisplayUpdates (1 byte) */ + stream_seek(s, 3); /* pad3Octets (3 bytes) */ + + if (allow > 0) + freerdp_write_rectangle_16(s, area); +} + +static void update_send_suppress_output(rdpUpdate* update, uint8 allow, RECTANGLE_16* area) +{ + STREAM* s; + rdpRdp* rdp = update->context->rdp; + + s = rdp_data_pdu_init(rdp); + update_write_suppress_output(s, allow, area); + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id); } static void update_send_surface_command(rdpUpdate* update, STREAM* s) @@ -386,6 +430,8 @@ void update_register_server_callbacks(rdpUpdate* update) update->Synchronize = update_send_synchronize; update->DesktopResize = update_send_desktop_resize; update->PointerSystem = update_send_pointer_system; + update->RefreshRect = update_send_refresh_rect; + update->SuppressOutput = update_send_suppress_output; update->SurfaceBits = update_send_surface_bits; update->SurfaceCommand = update_send_surface_command; } diff --git a/libfreerdp-core/window.c b/libfreerdp-core/window.c index 1312b644a..18a054e02 100644 --- a/libfreerdp-core/window.c +++ b/libfreerdp-core/window.c @@ -142,7 +142,7 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN /* windowRects */ for (i = 0; i < window_state->numWindowRects; i++) { - rail_read_rectangle_16(s, &window_state->windowRects[i]); + freerdp_read_rectangle_16(s, &window_state->windowRects[i]); } } @@ -162,7 +162,7 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN /* visibilityRects */ for (i = 0; i < window_state->numVisibilityRects; i++) { - rail_read_rectangle_16(s, &window_state->visibilityRects[i]); + freerdp_read_rectangle_16(s, &window_state->visibilityRects[i]); } } } diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt index 0c10a50c2..7541ee902 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp-utils/CMakeLists.txt @@ -36,6 +36,7 @@ set(FREERDP_UTILS_SRCS pcap.c profiler.c rail.c + rect.c registry.c certstore.c semaphore.c diff --git a/libfreerdp-utils/rect.c b/libfreerdp-utils/rect.c new file mode 100644 index 000000000..08cdea7fd --- /dev/null +++ b/libfreerdp-utils/rect.c @@ -0,0 +1,56 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Rectangle Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void freerdp_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_read_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_read_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_read_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_read_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +void freerdp_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_write_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_write_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_write_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_write_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +RECTANGLE_16* freerdp_rectangle_16_new(uint16 left, uint16 top, uint16 right, uint16 bottom) +{ + RECTANGLE_16* rectangle_16 = xnew(RECTANGLE_16); + + rectangle_16->left = left; + rectangle_16->top = top; + rectangle_16->right = right; + rectangle_16->bottom = bottom; + + return rectangle_16; +} + +void freerdp_rectangle_16_free(RECTANGLE_16* rectangle_16) +{ + xfree(rectangle_16); +}