From cd135ceacb8202fa6bca15c0c5ae45ffb369e767 Mon Sep 17 00:00:00 2001 From: kubistika Date: Mon, 20 May 2019 14:05:32 +0300 Subject: [PATCH] libfreerdp/core: Export monitor layout PDU * Move update notification related functions to new display.c: Not related to `rdp.c`. * Rename `rdp_write_monitor_layout_pdu` to `display_write_monitor_layout_pdu`. * Add internal `display_convert_rdp_monitor_to_monitor_def` instead of doing the conversion inside `display_write_monitor_layout_pdu`. --- include/freerdp/display.h | 36 +++++++++++++++ libfreerdp/core/CMakeLists.txt | 4 +- libfreerdp/core/activation.c | 20 ++++---- libfreerdp/core/display.c | 83 ++++++++++++++++++++++++++++++++++ libfreerdp/core/display.h | 29 ++++++++++++ libfreerdp/core/rdp.c | 23 ---------- libfreerdp/core/rdp.h | 3 -- server/proxy/pf_client.c | 1 + 8 files changed, 164 insertions(+), 35 deletions(-) create mode 100644 include/freerdp/display.h create mode 100644 libfreerdp/core/display.c create mode 100644 libfreerdp/core/display.h diff --git a/include/freerdp/display.h b/include/freerdp/display.h new file mode 100644 index 000000000..a884ec3d3 --- /dev/null +++ b/include/freerdp/display.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display update notifications + * + * Copyright 2019 Kobi Mizrachi + * + * 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 FREERDP_DISPLAY_H +#define FREERDP_DISPLAY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +FREERDP_API BOOL freerdp_display_send_monitor_layout(rdpContext* context, UINT32 monitorCount, + const MONITOR_DEF* monitorDefArray); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_DISPLAY_UPDATE_H */ diff --git a/libfreerdp/core/CMakeLists.txt b/libfreerdp/core/CMakeLists.txt index 812789de0..f9f830064 100644 --- a/libfreerdp/core/CMakeLists.txt +++ b/libfreerdp/core/CMakeLists.txt @@ -129,7 +129,9 @@ set(${MODULE_PREFIX}_SRCS listener.c listener.h peer.c - peer.h) + peer.h + display.c + display.h) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_GATEWAY_SRCS}) diff --git a/libfreerdp/core/activation.c b/libfreerdp/core/activation.c index 1537dc836..f23016baf 100644 --- a/libfreerdp/core/activation.c +++ b/libfreerdp/core/activation.c @@ -22,6 +22,7 @@ #endif #include "activation.h" +#include "display.h" /* static const char* const CTRLACTION_STRINGS[] = @@ -341,22 +342,25 @@ BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s) peer->AdjustMonitorsLayout(peer)) { /* client supports the monitorLayout PDU, let's send him the monitors if any */ - wStream* st = rdp_data_pdu_init(rdp); - BOOL r; + MONITOR_DEF* monitors = (MONITOR_DEF*) calloc(settings->MonitorCount, sizeof(MONITOR_DEF)); - if (!st) + if (!monitors) return FALSE; - if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray)) + if (!display_convert_rdp_monitor_to_monitor_def(settings->MonitorCount, settings->MonitorDefArray, + &monitors)) { - Stream_Release(st); + free(monitors); return FALSE; } - r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0); - - if (!r) + if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount, monitors)) + { + free(monitors); return FALSE; + } + + free(monitors); } if (!rdp_send_server_font_map_pdu(rdp)) diff --git a/libfreerdp/core/display.c b/libfreerdp/core/display.c new file mode 100644 index 000000000..4ceb0bbb0 --- /dev/null +++ b/libfreerdp/core/display.c @@ -0,0 +1,83 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display update notifications + * + * Copyright 2019 Kobi Mizrachi + * + * 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 "display.h" + +BOOL display_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, + const MONITOR_DEF* monitorDefArray) +{ + UINT32 index; + const MONITOR_DEF* monitor; + + if (!Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20))) + return FALSE; + + Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ + + for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++) + { + Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */ + Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */ + Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */ + Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ + Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */ + } + + return TRUE; +} + +BOOL display_convert_rdp_monitor_to_monitor_def(UINT32 monitorCount, + const rdpMonitor* monitorDefArray, MONITOR_DEF** result) +{ + UINT32 index; + const rdpMonitor* monitor; + + if (!monitorDefArray || !(*result)) + return FALSE; + + for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++) + { + MONITOR_DEF* current = (*result + index); + current->left = monitor->x; /* left (4 bytes) */ + current->top = monitor->y; /* top (4 bytes) */ + current->right = monitor->x + monitor->width - 1; /* right (4 bytes) */ + current->bottom = monitor->y + monitor->height - 1; /* bottom (4 bytes) */ + current->flags = monitor->is_primary ? MONITOR_PRIMARY : 0x0; /* flags (4 bytes) */ + } + + return TRUE; +} + +BOOL freerdp_display_send_monitor_layout(rdpContext* context, UINT32 monitorCount, + const MONITOR_DEF* monitorDefArray) +{ + rdpRdp* rdp = context->rdp; + wStream* st = rdp_data_pdu_init(rdp); + + if (!st) + return FALSE; + + if (!display_write_monitor_layout_pdu(st, monitorCount, monitorDefArray)) + { + Stream_Release(st); + return FALSE; + } + + return rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0); +} diff --git a/libfreerdp/core/display.h b/libfreerdp/core/display.h new file mode 100644 index 000000000..25322020d --- /dev/null +++ b/libfreerdp/core/display.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Display update notifications + * + * Copyright 2019 Kobi Mizrachi + * + * 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 FREERDP_LIB_CORE_DISPLAY_H +#define FREERDP_LIB_CORE_DISPLAY_H + +#include +#include "rdp.h" + +FREERDP_LOCAL BOOL display_convert_rdp_monitor_to_monitor_def(UINT32 monitorCount, + const rdpMonitor* monitorDefArray, MONITOR_DEF** result); + +#endif /* FREERDP_LIB_CORE_DISPLAY_H */ diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 106d780e0..de3c97c97 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -807,29 +807,6 @@ static BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s) return ret; } -BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, - const rdpMonitor* monitorDefArray) -{ - UINT32 index; - const rdpMonitor* monitor; - - if (!Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20))) - return FALSE; - - Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ - - for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++) - { - Stream_Write_UINT32(s, monitor->x); /* left (4 bytes) */ - Stream_Write_UINT32(s, monitor->y); /* top (4 bytes) */ - Stream_Write_UINT32(s, monitor->x + monitor->width - 1); /* right (4 bytes) */ - Stream_Write_UINT32(s, monitor->y + monitor->height - 1); /* bottom (4 bytes) */ - Stream_Write_UINT32(s, monitor->is_primary ? 0x01 : 0x00); /* flags (4 bytes) */ - } - - return TRUE; -} - int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { BYTE type; diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 9df6c0a49..31011f410 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -223,9 +223,6 @@ FREERDP_LOCAL int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s); FREERDP_LOCAL void rdp_read_flow_control_pdu(wStream* s, UINT16* type); -FREERDP_LOCAL BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, - const rdpMonitor* monitorDefArray); - FREERDP_LOCAL int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra); diff --git a/server/proxy/pf_client.c b/server/proxy/pf_client.c index 4f5430bb6..97335363d 100644 --- a/server/proxy/pf_client.c +++ b/server/proxy/pf_client.c @@ -29,6 +29,7 @@ #include #include +#include #include #include