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