21#include <freerdp/config.h>
27#include <winpr/assert.h>
28#include <winpr/stream.h>
29#include <winpr/sysinfo.h>
31#include "ainput_main.h"
32#include <freerdp/channels/log.h>
33#include <freerdp/client/channels.h>
34#include <freerdp/client/ainput.h>
35#include <freerdp/channels/ainput.h>
37#include "../common/ainput_common.h"
39#define TAG CHANNELS_TAG("ainput.client")
41typedef struct AINPUT_PLUGIN_ AINPUT_PLUGIN;
45 AInputClientContext* context;
55static UINT ainput_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
wStream* data)
58 AINPUT_PLUGIN* ainput = NULL;
61 WINPR_ASSERT(callback);
64 ainput = (AINPUT_PLUGIN*)callback->plugin;
67 if (!Stream_CheckAndLogRequiredLength(TAG, data, 2))
69 Stream_Read_UINT16(data, type);
72 case MSG_AINPUT_VERSION:
73 if (!Stream_CheckAndLogRequiredLength(TAG, data, 8))
75 Stream_Read_UINT32(data, ainput->MajorVersion);
76 Stream_Read_UINT32(data, ainput->MinorVersion);
79 WLog_WARN(TAG,
"Received unsupported message type 0x%04" PRIx16, type);
86static UINT ainput_send_input_event(AInputClientContext* context, UINT64 flags, INT32 x, INT32 y)
88 AINPUT_PLUGIN* ainput = NULL;
90 BYTE buffer[32] = { 0 };
93 wStream* s = Stream_StaticInit(&sbuffer, buffer,
sizeof(buffer));
96 WINPR_ASSERT(context);
98 time = GetTickCount64();
99 ainput = (AINPUT_PLUGIN*)context->handle;
100 WINPR_ASSERT(ainput);
102 if (ainput->MajorVersion != AINPUT_VERSION_MAJOR)
104 WLog_WARN(TAG,
"Unsupported channel version %" PRIu32
".%" PRIu32
", aborting.",
105 ainput->MajorVersion, ainput->MinorVersion);
106 return CHANNEL_RC_UNSUPPORTED_VERSION;
108 callback = ainput->base.listener_callback->channel_callback;
109 WINPR_ASSERT(callback);
112 char ebuffer[128] = { 0 };
113 WLog_VRB(TAG,
"sending timestamp=0x%08" PRIx64
", flags=%s, %" PRId32
"x%" PRId32, time,
114 ainput_flags_to_string(flags, ebuffer,
sizeof(ebuffer)), x, y);
118 Stream_Write_UINT16(s, MSG_AINPUT_MOUSE);
121 Stream_Write_UINT64(s, time);
122 Stream_Write_UINT64(s, flags);
123 Stream_Write_INT32(s, x);
124 Stream_Write_INT32(s, y);
125 Stream_SealLength(s);
128 WINPR_ASSERT(callback->channel);
129 WINPR_ASSERT(callback->channel->Write);
130 return callback->channel->Write(callback->channel, (ULONG)Stream_Length(s), Stream_Buffer(s),
139static UINT ainput_on_close(IWTSVirtualChannelCallback* pChannelCallback)
145 return CHANNEL_RC_OK;
149 WINPR_ATTR_UNUSED rdpSettings* settings)
151 AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)base;
152 AInputClientContext* context = (AInputClientContext*)calloc(1,
sizeof(AInputClientContext));
154 return CHANNEL_RC_NO_MEMORY;
156 context->handle = (
void*)base;
157 context->AInputSendInputEvent = ainput_send_input_event;
159 ainput->context = context;
160 ainput->base.iface.pInterface = context;
161 return CHANNEL_RC_OK;
166 AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)base;
167 free(ainput->context);
170static const IWTSVirtualChannelCallback ainput_functions = { ainput_on_data_received,
172 ainput_on_close, NULL };
179FREERDP_ENTRY_POINT(UINT VCAPITYPE ainput_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints))
181 return freerdp_generic_DVCPluginEntry(pEntryPoints, TAG, AINPUT_DVC_CHANNEL_NAME,
183 &ainput_functions, init_plugin_cb, terminate_plugin_cb);