From c4e14f7fd6277f1deb533dc0fcd6fae6aec8119b Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 19 Jan 2022 09:26:57 +0100 Subject: [PATCH] Added Advanced Input Channel support to sample server --- server/Sample/CMakeLists.txt | 16 +++--- server/Sample/sf_ainput.c | 94 ++++++++++++++++++++++++++++++++++++ server/Sample/sf_ainput.h | 37 ++++++++++++++ server/Sample/sfreerdp.c | 34 +++++++++++-- server/Sample/sfreerdp.h | 7 +++ 5 files changed, 178 insertions(+), 10 deletions(-) create mode 100644 server/Sample/sf_ainput.c create mode 100644 server/Sample/sf_ainput.h diff --git a/server/Sample/CMakeLists.txt b/server/Sample/CMakeLists.txt index 9e31827e3..1212eaf31 100644 --- a/server/Sample/CMakeLists.txt +++ b/server/Sample/CMakeLists.txt @@ -18,7 +18,7 @@ set(MODULE_NAME "sfreerdp-server") set(MODULE_PREFIX "FREERDP_SERVER_SAMPLE") -set(${MODULE_PREFIX}_SRCS +set(SRCS sfreerdp.c sfreerdp.h sf_audin.c @@ -28,6 +28,10 @@ set(${MODULE_PREFIX}_SRCS sf_encomsp.c sf_encomsp.h) +if (CHANNEL_AINPUT_SERVER) + list(APPEND SRCS sf_ainput.c sf_ainput.h) +endif() + # On windows create dll version information. # Vendor, product and year are already set in top level CMakeLists.txt if (WIN32) @@ -41,15 +45,15 @@ if (WIN32) ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) - set ( ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + set ( SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) endif() -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_executable(${MODULE_NAME} ${SRCS}) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-server) -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr freerdp) +list(APPEND LIBS freerdp-server) +list(APPEND LIBS winpr freerdp) -target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) +target_link_libraries(${MODULE_NAME} ${LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) if (WITH_DEBUG_SYMBOLS AND MSVC) install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT symbols) diff --git a/server/Sample/sf_ainput.c b/server/Sample/sf_ainput.c new file mode 100644 index 000000000..439d90e2f --- /dev/null +++ b/server/Sample/sf_ainput.c @@ -0,0 +1,94 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server (Advanced Input) + * + * Copyright 2022 Armin Novak + * Copyright 2022 Thincast Technologies GmbH + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "sfreerdp.h" + +#include "sf_ainput.h" + +#include +#include + +#include +#define TAG SERVER_TAG("sample.ainput") + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT sf_peer_ainput_mouse_event(ainput_server_context* context, UINT64 flags, INT32 x, + INT32 y) +{ + /* TODO: Implement */ + WINPR_ASSERT(context); + + WLog_WARN(TAG, "%s not implemented: 0x%08" PRIx64 ", %" PRId32 "x%" PRId32, __FUNCTION__, flags, + x, y); + return CHANNEL_RC_OK; +} + +void sf_peer_ainput_init(testPeerContext* context) +{ + WINPR_ASSERT(context); + + context->ainput = ainput_server_context_new(context->vcm); + WINPR_ASSERT(context->ainput); + + context->ainput->rdpcontext = &context->_p; + context->ainput->data = context; + + context->ainput->MouseEvent = sf_peer_ainput_mouse_event; +} + +BOOL sf_peer_ainput_start(testPeerContext* context) +{ + if (!context || !context->ainput || !context->ainput->Open) + return FALSE; + + return context->ainput->Open(context->ainput) == CHANNEL_RC_OK; +} + +BOOL sf_peer_ainput_stop(testPeerContext* context) +{ + if (!context || !context->ainput || !context->ainput->Close) + return FALSE; + + return context->ainput->Close(context->ainput) == CHANNEL_RC_OK; +} + +BOOL sf_peer_ainput_running(testPeerContext* context) +{ + if (!context || !context->ainput || !context->ainput->IsOpen) + return FALSE; + + return context->ainput->IsOpen(context->ainput); +} + +void sf_peer_ainput_uninit(testPeerContext* context) +{ + ainput_server_context_free(context->ainput); +} diff --git a/server/Sample/sf_ainput.h b/server/Sample/sf_ainput.h new file mode 100644 index 000000000..3cf78d536 --- /dev/null +++ b/server/Sample/sf_ainput.h @@ -0,0 +1,37 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server (Advanced Input) + * + * Copyright 2022 Armin Novak + * Copyright 2022 Thincast Technologies GmbH + * + * 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_SERVER_SAMPLE_SF_AINPUT_H +#define FREERDP_SERVER_SAMPLE_SF_AINPUT_H + +#include +#include +#include + +#include "sfreerdp.h" + +void sf_peer_ainput_init(testPeerContext* context); +void sf_peer_ainput_uninit(testPeerContext* context); + +BOOL sf_peer_ainput_running(testPeerContext* context); +BOOL sf_peer_ainput_start(testPeerContext* context); +BOOL sf_peer_ainput_stop(testPeerContext* context); + +#endif /* FREERDP_SERVER_SAMPLE_SF_AINPUT_H */ diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 0dd93e009..4776640e5 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -46,6 +46,7 @@ #include #include +#include "sf_ainput.h" #include "sf_audin.h" #include "sf_rdpsnd.h" #include "sf_encomsp.h" @@ -95,6 +96,10 @@ static void test_peer_context_free(freerdp_peer* client, rdpContext* ctx) sf_peer_audin_uninit(context); +#if defined(CHANNEL_AINPUT_SERVER) + sf_peer_ainput_uninit(context); +#endif + rdpsnd_server_context_free(context->rdpsnd); encomsp_server_context_free(context->encomsp); @@ -696,6 +701,11 @@ static BOOL tf_peer_post_connect(freerdp_peer* client) /* Dynamic Virtual Channels */ sf_peer_audin_init(context); /* Audio Input */ + +#if defined(CHANNEL_AINPUT_SERVER) + sf_peer_ainput_init(context); +#endif + /* Return FALSE here would stop the execution of the peer main loop. */ return TRUE; } @@ -785,7 +795,7 @@ static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) update->DesktopResize(update->context); context->activated = FALSE; } - else if ((flags & 0x4000) && code == 0x2E) /* 'c' key */ + else if ((flags & 0x4000) && code == RDP_SCANCODE_KEY_C) /* 'c' key */ { if (context->debug_channel) { @@ -793,16 +803,22 @@ static BOOL tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test2", 5, &written); } } - else if ((flags & 0x4000) && code == 0x2D) /* 'x' key */ + else if ((flags & 0x4000) && code == RDP_SCANCODE_KEY_X) /* 'x' key */ { WINPR_ASSERT(client->Close); client->Close(client); } - else if ((flags & 0x4000) && code == 0x13) /* 'r' key */ + else if ((flags & 0x4000) && code == RDP_SCANCODE_KEY_R) /* 'r' key */ { context->audin_open = !context->audin_open; } - else if ((flags & 0x4000) && code == 0x1F) /* 's' key */ +#if defined(CHANNEL_AINPUT_SERVER) + else if ((flags & 0x4000) && code == RDP_SCANCODE_KEY_I) /* 'i' key */ + { + context->ainput_open = !context->ainput_open; + } +#endif + else if ((flags & 0x4000) && code == RDP_SCANCODE_KEY_S) /* 's' key */ { } @@ -1096,6 +1112,16 @@ static DWORD WINAPI test_peer_mainloop(LPVOID arg) sf_peer_audin_stop(context); } +#if defined(CHANNEL_AINPUT_SERVER) + if (sf_peer_ainput_running(context) != context->ainput_open) + { + if (!sf_peer_ainput_running(context)) + sf_peer_ainput_start(context); + else + sf_peer_ainput_stop(context); + } +#endif + break; case DRDYNVC_STATE_FAILED: diff --git a/server/Sample/sfreerdp.h b/server/Sample/sfreerdp.h index f686f72d5..212556a4d 100644 --- a/server/Sample/sfreerdp.h +++ b/server/Sample/sfreerdp.h @@ -25,6 +25,9 @@ #include #include #include +#if defined(CHANNEL_AINPUT_SERVER) +#include +#endif #include #include #include @@ -55,6 +58,10 @@ struct test_peer_context HANDLE debug_channel_thread; audin_server_context* audin; BOOL audin_open; +#if defined(CHANNEL_AINPUT_SERVER) + ainput_server_context* ainput; + BOOL ainput_open; +#endif UINT32 frame_id; RdpsndServerContext* rdpsnd; EncomspServerContext* encomsp;