FreeRDP
Loading...
Searching...
No Matches
pf_input.c
1
24#include <winpr/assert.h>
25
26#include <freerdp/message.h>
27
28#include "pf_input.h"
29#include "pf_client.h"
30#include "pf_server.h"
31#include <freerdp/server/proxy/proxy_config.h>
32
33#include "proxy_modules.h"
34
35WINPR_ATTR_NODISCARD
36static BOOL pf_server_check_and_sync_input_state(pClientContext* pc)
37{
38 WINPR_ASSERT(pc);
39
40 if (!freerdp_is_active_state(&pc->cctx.context))
41 return FALSE;
42 if (pc->input_state_sync_pending)
43 {
44 BOOL rc = freerdp_input_send_synchronize_event(pc->cctx.context.input, pc->input_state);
45 if (rc)
46 pc->input_state_sync_pending = FALSE;
47 }
48 return TRUE;
49}
50
51WINPR_ATTR_NODISCARD
52static BOOL pf_server_synchronize_event(rdpInput* input, UINT32 flags)
53{
54 WINPR_ASSERT(input);
55 pServerContext* ps = (pServerContext*)input->context;
56 WINPR_ASSERT(ps);
57 WINPR_ASSERT(ps->pdata);
58
59 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
60 if (!pc)
61 return TRUE;
62
63 return pf_client_post_message(pc, MakeMessageId(Input, SynchronizeEvent), flags, nullptr);
64}
65
66WINPR_ATTR_NODISCARD
67static BOOL pf_server_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
68{
69 proxyKeyboardEventInfo event = WINPR_C_ARRAY_INIT;
70
71 WINPR_ASSERT(input);
72 pServerContext* ps = (pServerContext*)input->context;
73 WINPR_ASSERT(ps);
74 WINPR_ASSERT(ps->pdata);
75
76 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
77 if (!pc)
78 return TRUE;
79
80 const proxyConfig* config = ps->pdata->config;
81 WINPR_ASSERT(config);
82
83 if (!config->Keyboard)
84 return TRUE;
85
86 event.flags = flags;
87 event.rdp_scan_code = code;
88
89 if (pf_modules_run_filter(pc->pdata->module, FILTER_TYPE_KEYBOARD, pc->pdata, &event))
90 return pf_client_post_message(pc, MakeMessageId(Input, KeyboardEvent), flags,
91 (void*)(size_t)code);
92
93 return TRUE;
94}
95
96WINPR_ATTR_NODISCARD
97static BOOL pf_server_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
98{
99 proxyUnicodeEventInfo event = WINPR_C_ARRAY_INIT;
100
101 WINPR_ASSERT(input);
102 pServerContext* ps = (pServerContext*)input->context;
103 WINPR_ASSERT(ps);
104 WINPR_ASSERT(ps->pdata);
105
106 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
107 if (!pc)
108 return TRUE;
109
110 const proxyConfig* config = ps->pdata->config;
111 WINPR_ASSERT(config);
112
113 if (!config->Keyboard)
114 return TRUE;
115
116 event.flags = flags;
117 event.code = code;
118 if (pf_modules_run_filter(pc->pdata->module, FILTER_TYPE_UNICODE, pc->pdata, &event))
119 return pf_client_post_message(pc, MakeMessageId(Input, UnicodeKeyboardEvent), flags,
120 (void*)(size_t)code);
121 return TRUE;
122}
123
124WINPR_ATTR_NODISCARD
125static BOOL pf_server_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
126{
127 proxyMouseEventInfo event = WINPR_C_ARRAY_INIT;
128
129 WINPR_ASSERT(input);
130 pServerContext* ps = (pServerContext*)input->context;
131 WINPR_ASSERT(ps);
132 WINPR_ASSERT(ps->pdata);
133
134 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
135 if (!pc)
136 return TRUE;
137
138 const proxyConfig* config = ps->pdata->config;
139 WINPR_ASSERT(config);
140
141 if (!config->Mouse)
142 return TRUE;
143
144 event.flags = flags;
145 event.x = x;
146 event.y = y;
147
148 if (pf_modules_run_filter(pc->pdata->module, FILTER_TYPE_MOUSE, pc->pdata, &event))
149 return pf_client_post_message(pc, MakeMessageId(Input, MouseEvent), flags,
150 (void*)(size_t)(((UINT32)x << 16) | y));
151
152 return TRUE;
153}
154
155WINPR_ATTR_NODISCARD
156static BOOL pf_server_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
157{
158 proxyMouseExEventInfo event = WINPR_C_ARRAY_INIT;
159
160 WINPR_ASSERT(input);
161
162 pServerContext* ps = (pServerContext*)input->context;
163 WINPR_ASSERT(ps);
164 WINPR_ASSERT(ps->pdata);
165
166 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
167 if (!pc)
168 return TRUE;
169
170 const proxyConfig* config = ps->pdata->config;
171 WINPR_ASSERT(config);
172
173 if (!config->Mouse)
174 return TRUE;
175
176 event.flags = flags;
177 event.x = x;
178 event.y = y;
179 if (pf_modules_run_filter(pc->pdata->module, FILTER_TYPE_MOUSE_EX, pc->pdata, &event))
180 return pf_client_post_message(pc, MakeMessageId(Input, ExtendedMouseEvent), flags,
181 (void*)(size_t)(((UINT32)x << 16) | y));
182 return TRUE;
183}
184
185BOOL pf_client_process_input_message(pClientContext* pc, const wMessage* msg)
186{
187 WINPR_ASSERT(pc);
188 WINPR_ASSERT(msg);
189
190 const UINT32 type = GetMessageType(msg->id);
191 if (type == Input_SynchronizeEvent)
192 {
193 pc->input_state = (UINT32)(size_t)msg->wParam;
194 pc->input_state_sync_pending = TRUE;
195 }
196
197 if (!pf_server_check_and_sync_input_state(pc))
198 return TRUE;
199
200 rdpInput* input = pc->cctx.context.input;
201 const UINT16 flags = (UINT16)(size_t)msg->wParam;
202 const UINT32 arg = (UINT32)(size_t)msg->lParam;
203 const UINT16 x = (UINT16)(arg >> 16);
204 const UINT16 y = (UINT16)(arg & 0xFFFF);
205
206 switch (type)
207 {
208 case Input_SynchronizeEvent:
209 return TRUE;
210 case Input_KeyboardEvent:
211 return freerdp_input_send_keyboard_event(input, flags, (UINT8)arg);
212 case Input_UnicodeKeyboardEvent:
213 return freerdp_input_send_unicode_keyboard_event(input, flags, (UINT16)arg);
214 case Input_MouseEvent:
215 return freerdp_input_send_mouse_event(input, flags, x, y);
216 case Input_ExtendedMouseEvent:
217 return freerdp_input_send_extended_mouse_event(input, flags, x, y);
218 default:
219 return FALSE;
220 }
221}
222
223void pf_server_register_input_callbacks(rdpInput* input)
224{
225 WINPR_ASSERT(input);
226
227 input->SynchronizeEvent = pf_server_synchronize_event;
228 input->KeyboardEvent = pf_server_keyboard_event;
229 input->UnicodeKeyboardEvent = pf_server_unicode_keyboard_event;
230 input->MouseEvent = pf_server_mouse_event;
231 input->ExtendedMouseEvent = pf_server_extended_mouse_event;
232}