21 #include <freerdp/config.h>
26 #include <winpr/crt.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")
41 typedef struct AINPUT_PLUGIN_ AINPUT_PLUGIN;
45 AInputClientContext* context;
55 static 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);
86 static 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),
139 static UINT ainput_on_close(IWTSVirtualChannelCallback* pChannelCallback)
145 return CHANNEL_RC_OK;
148 static UINT init_plugin_cb(
GENERIC_DYNVC_PLUGIN* base, rdpContext* rcontext, rdpSettings* settings)
150 AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)base;
151 AInputClientContext* context = (AInputClientContext*)calloc(1,
sizeof(AInputClientContext));
153 return CHANNEL_RC_NO_MEMORY;
155 context->handle = (
void*)base;
156 context->AInputSendInputEvent = ainput_send_input_event;
158 ainput->context = context;
159 ainput->base.iface.pInterface = context;
160 return CHANNEL_RC_OK;
165 AINPUT_PLUGIN* ainput = (AINPUT_PLUGIN*)base;
166 free(ainput->context);
169 static const IWTSVirtualChannelCallback ainput_functions = { ainput_on_data_received,
171 ainput_on_close, NULL };
178 FREERDP_ENTRY_POINT(UINT VCAPITYPE ainput_DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints))
180 return freerdp_generic_DVCPluginEntry(pEntryPoints, TAG, AINPUT_DVC_CHANNEL_NAME,
182 &ainput_functions, init_plugin_cb, terminate_plugin_cb);