FreeRDP
Loading...
Searching...
No Matches
shadow_subsystem.c
1
19#include <freerdp/config.h>
20
21#include "shadow.h"
22
23#include "shadow_subsystem.h"
24
25static pfnShadowSubsystemEntry pSubsystemEntry = nullptr;
26
27void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry)
28{
29 pSubsystemEntry = pEntry;
30}
31
32WINPR_ATTR_NODISCARD
33static int shadow_subsystem_load_entry_points(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
34{
35 WINPR_ASSERT(pEntryPoints);
36 ZeroMemory(pEntryPoints, sizeof(RDP_SHADOW_ENTRY_POINTS));
37
38 if (!pSubsystemEntry)
39 return -1;
40
41 if (pSubsystemEntry(pEntryPoints) < 0)
42 return -1;
43
44 return 1;
45}
46
47rdpShadowSubsystem* shadow_subsystem_new(void)
48{
49 RDP_SHADOW_ENTRY_POINTS ep = WINPR_C_ARRAY_INIT;
50
51 if (shadow_subsystem_load_entry_points(&ep) < 0)
52 return nullptr;
53
54 if (!ep.New)
55 return nullptr;
56
57 rdpShadowSubsystem* subsystem = ep.New();
58
59 if (!subsystem)
60 return nullptr;
61
62 subsystem->ep = ep;
63
64 return subsystem;
65}
66
67void shadow_subsystem_free(rdpShadowSubsystem* subsystem)
68{
69 if (subsystem && subsystem->ep.Free)
70 subsystem->ep.Free(subsystem);
71}
72
73int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server)
74{
75 int status = -1;
76
77 if (!subsystem || !subsystem->ep.Init)
78 return -1;
79
80 subsystem->server = server;
81 subsystem->selectedMonitor = server->selectedMonitor;
82
83 if (!(subsystem->MsgPipe = MessagePipe_New()))
84 goto fail;
85
86 if (!(subsystem->updateEvent = shadow_multiclient_new()))
87 goto fail;
88
89 status = subsystem->ep.Init(subsystem);
90 if (status >= 0)
91 return status;
92
93fail:
94 if (subsystem->MsgPipe)
95 {
96 MessagePipe_Free(subsystem->MsgPipe);
97 subsystem->MsgPipe = nullptr;
98 }
99
100 if (subsystem->updateEvent)
101 {
102 shadow_multiclient_free(subsystem->updateEvent);
103 subsystem->updateEvent = nullptr;
104 }
105
106 return status;
107}
108
109static void shadow_subsystem_free_queued_message(void* obj)
110{
111 wMessage* message = (wMessage*)obj;
112 if (message->Free)
113 {
114 message->Free(message);
115 message->Free = nullptr;
116 }
117}
118
119void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
120{
121 if (!subsystem)
122 return;
123
124 if (subsystem->ep.Uninit)
125 subsystem->ep.Uninit(subsystem);
126
127 if (subsystem->MsgPipe)
128 {
129 wObject* obj1 = nullptr;
130 wObject* obj2 = nullptr;
131 /* Release resource in messages before free */
132 obj1 = MessageQueue_Object(subsystem->MsgPipe->In);
133
134 obj1->fnObjectFree = shadow_subsystem_free_queued_message;
135 MessageQueue_Clear(subsystem->MsgPipe->In);
136
137 obj2 = MessageQueue_Object(subsystem->MsgPipe->Out);
138 obj2->fnObjectFree = shadow_subsystem_free_queued_message;
139 MessageQueue_Clear(subsystem->MsgPipe->Out);
140 MessagePipe_Free(subsystem->MsgPipe);
141 subsystem->MsgPipe = nullptr;
142 }
143
144 if (subsystem->updateEvent)
145 {
146 shadow_multiclient_free(subsystem->updateEvent);
147 subsystem->updateEvent = nullptr;
148 }
149}
150
151int shadow_subsystem_start(rdpShadowSubsystem* subsystem)
152{
153 int status = 0;
154
155 if (!subsystem || !subsystem->ep.Start)
156 return -1;
157
158 status = subsystem->ep.Start(subsystem);
159
160 return status;
161}
162
163int shadow_subsystem_stop(rdpShadowSubsystem* subsystem)
164{
165 int status = 0;
166
167 if (!subsystem || !subsystem->ep.Stop)
168 return -1;
169
170 status = subsystem->ep.Stop(subsystem);
171
172 return status;
173}
174
175UINT32 shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors)
176{
177 UINT32 numMonitors = 0;
178 RDP_SHADOW_ENTRY_POINTS ep;
179
180 if (shadow_subsystem_load_entry_points(&ep) < 0)
181 return 0;
182
183 numMonitors = ep.EnumMonitors(monitors, maxMonitors);
184
185 return numMonitors;
186}
187
194#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
195int shadow_subsystem_pointer_convert_alpha_pointer_data(
196 const BYTE* WINPR_RESTRICT pixels, BOOL premultiplied, UINT32 width, UINT32 height,
197 SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* WINPR_RESTRICT pointerColor)
198{
199 return shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
200 pixels, PIXEL_FORMAT_BGRX32, premultiplied, width, height, pointerColor);
201}
202#endif
203
204int shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
205 const BYTE* pixels, UINT32 format, BOOL premultiplied, UINT32 width, UINT32 height,
207{
208 UINT32 xorStep = 0;
209 UINT32 andStep = 0;
210 UINT32 andBit = 0;
211 BYTE* andBits = nullptr;
212 UINT32 andPixel = 0;
213 const size_t bpp = FreeRDPGetBytesPerPixel(format);
214
215 xorStep = (width * 3);
216 xorStep += (xorStep % 2);
217
218 andStep = ((width + 7) / 8);
219 andStep += (andStep % 2);
220
221 pointerColor->lengthXorMask = height * xorStep;
222 pointerColor->xorMaskData = (BYTE*)calloc(1, pointerColor->lengthXorMask);
223
224 if (!pointerColor->xorMaskData)
225 return -1;
226
227 pointerColor->lengthAndMask = height * andStep;
228 pointerColor->andMaskData = (BYTE*)calloc(1, pointerColor->lengthAndMask);
229
230 if (!pointerColor->andMaskData)
231 {
232 free(pointerColor->xorMaskData);
233 pointerColor->xorMaskData = nullptr;
234 return -1;
235 }
236
237 for (size_t y = 0; y < height; y++)
238 {
239 const BYTE* pSrc8 = &pixels[(width * bpp) * (height - 1 - y)];
240 BYTE* pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
241
242 andBit = 0x80;
243 andBits = &(pointerColor->andMaskData[andStep * y]);
244
245 for (size_t x = 0; x < width; x++)
246 {
247 BYTE B = 0;
248 BYTE G = 0;
249 BYTE R = 0;
250 BYTE A = 0;
251
252 const UINT32 color = FreeRDPReadColor(&pSrc8[x * bpp], format);
253 FreeRDPSplitColor(color, format, &R, &G, &B, &A, nullptr);
254
255 andPixel = 0;
256
257 if (A < 64)
258 A = 0; /* pixel cannot be partially transparent */
259
260 if (!A)
261 {
262 /* transparent pixel: XOR = black, AND = 1 */
263 andPixel = 1;
264 B = G = R = 0;
265 }
266 else
267 {
268 if (premultiplied)
269 {
270 B = (B * 0xFF) / A;
271 G = (G * 0xFF) / A;
272 R = (R * 0xFF) / A;
273 }
274 }
275
276 *pDst8++ = B;
277 *pDst8++ = G;
278 *pDst8++ = R;
279
280 if (andPixel)
281 *andBits |= andBit;
282 if (!(andBit >>= 1))
283 {
284 andBits++;
285 andBit = 0x80;
286 }
287 }
288 }
289
290 return 1;
291}
292
293void shadow_subsystem_frame_update(rdpShadowSubsystem* subsystem)
294{
295 shadow_multiclient_publish_and_wait(subsystem->updateEvent);
296}
This struct contains function pointer to initialize/free objects.
Definition collections.h:52
OBJECT_FREE_FN fnObjectFree
Definition collections.h:58