FreeRDP
Loading...
Searching...
No Matches
shadow_input.c
1
19#include <winpr/assert.h>
20#include <freerdp/config.h>
21
22#include <freerdp/log.h>
23#include "shadow.h"
24
25#define TAG SERVER_TAG("shadow.input")
26
27WINPR_ATTR_NODISCARD
28static BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
29{
30 WINPR_ASSERT(input);
31 rdpShadowClient* client = (rdpShadowClient*)input->context;
32 WINPR_ASSERT(client);
33 WINPR_ASSERT(client->server);
34 rdpShadowSubsystem* subsystem = client->server->subsystem;
35 WINPR_ASSERT(subsystem);
36
37 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
38 if (!client->mayInteract)
39 return TRUE;
40
41 return IFCALLRESULT(TRUE, subsystem->SynchronizeEvent, subsystem, client, flags);
42}
43
44WINPR_ATTR_NODISCARD
45static BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
46{
47 WINPR_ASSERT(input);
48 rdpShadowClient* client = (rdpShadowClient*)input->context;
49 WINPR_ASSERT(client);
50 WINPR_ASSERT(client->server);
51 rdpShadowSubsystem* subsystem = client->server->subsystem;
52 WINPR_ASSERT(subsystem);
53
54 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
55 if (!client->mayInteract)
56 return TRUE;
57
58 return IFCALLRESULT(TRUE, subsystem->KeyboardEvent, subsystem, client, flags, code);
59}
60
61WINPR_ATTR_NODISCARD
62static BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
63{
64 WINPR_ASSERT(input);
65 rdpShadowClient* client = (rdpShadowClient*)input->context;
66 WINPR_ASSERT(client);
67 WINPR_ASSERT(client->server);
68 rdpShadowSubsystem* subsystem = client->server->subsystem;
69 WINPR_ASSERT(subsystem);
70
71 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16, client->mayInteract ? "use" : "discard", flags);
72 if (!client->mayInteract)
73 return TRUE;
74
75 return IFCALLRESULT(TRUE, subsystem->UnicodeKeyboardEvent, subsystem, client, flags, code);
76}
77
78WINPR_ATTR_NODISCARD
79static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
80{
81 WINPR_ASSERT(input);
82 rdpShadowClient* client = (rdpShadowClient*)input->context;
83 WINPR_ASSERT(client);
84 WINPR_ASSERT(client->server);
85 rdpShadowSubsystem* subsystem = client->server->subsystem;
86 WINPR_ASSERT(subsystem);
87
88 if (client->server->shareSubRect)
89 {
90 x += client->server->subRect.left;
91 y += client->server->subRect.top;
92 }
93
94 if ((flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE)) == 0)
95 {
96 client->pointerX = x;
97 client->pointerY = y;
98
99 if ((client->pointerX == subsystem->pointerX) && (client->pointerY == subsystem->pointerY))
100 {
101 flags &= ~PTR_FLAGS_MOVE;
102
103 if (!(flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3)))
104 return TRUE;
105 }
106 }
107
108 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRIu16 ", y=%" PRIu16,
109 client->mayInteract ? "use" : "discard", flags, x, y);
110 if (!client->mayInteract)
111 return TRUE;
112
113 return IFCALLRESULT(TRUE, subsystem->MouseEvent, subsystem, client, flags, x, y);
114}
115
116WINPR_ATTR_NODISCARD
117static BOOL shadow_input_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
118{
119 WINPR_ASSERT(input);
120
121 rdpShadowClient* client = (rdpShadowClient*)input->context;
122 WINPR_ASSERT(client);
123 WINPR_ASSERT(client->server);
124
125 rdpShadowSubsystem* subsystem = client->server->subsystem;
126 WINPR_ASSERT(subsystem);
127
128 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRId16 ", y=%" PRId16,
129 client->mayInteract ? "use" : "discard", flags, xDelta, yDelta);
130 const uint16_t mask = PTR_FLAGS_MOVE | PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 |
131 PTR_FLAGS_BUTTON3 | PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2;
132 if ((flags & mask) != 0)
133 {
134 WLog_WARN(TAG, "Unknown flags 0x%04x", WINPR_CXX_COMPAT_CAST(unsigned, flags & ~mask));
135 }
136 if (!client->mayInteract)
137 return TRUE;
138
139 return IFCALLRESULT(TRUE, subsystem->RelMouseEvent, subsystem, client, flags, xDelta, yDelta);
140}
141
142WINPR_ATTR_NODISCARD
143static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
144{
145 WINPR_ASSERT(input);
146 rdpShadowClient* client = (rdpShadowClient*)input->context;
147 WINPR_ASSERT(client);
148 WINPR_ASSERT(client->server);
149 rdpShadowSubsystem* subsystem = client->server->subsystem;
150 WINPR_ASSERT(subsystem);
151
152 if (client->server->shareSubRect)
153 {
154 x += client->server->subRect.left;
155 y += client->server->subRect.top;
156 }
157
158 client->pointerX = x;
159 client->pointerY = y;
160
161 WLog_DBG(TAG, "[%s] flags=0x%04" PRIx16 ", x=%" PRIu16 ", y=%" PRIu16,
162 client->mayInteract ? "use" : "discard", flags, x, y);
163 if (!client->mayInteract)
164 return TRUE;
165
166 return IFCALLRESULT(TRUE, subsystem->ExtendedMouseEvent, subsystem, client, flags, x, y);
167}
168
169void shadow_input_register_callbacks(rdpInput* input)
170{
171 WINPR_ASSERT(input);
172 input->SynchronizeEvent = shadow_input_synchronize_event;
173 input->KeyboardEvent = shadow_input_keyboard_event;
174 input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event;
175 input->MouseEvent = shadow_input_mouse_event;
176 input->ExtendedMouseEvent = shadow_input_extended_mouse_event;
177 input->RelMouseEvent = shadow_input_rel_mouse_event;
178}